2015-07-21 75 views
0

使用C++,獲取堆棧指針或在X64上獲取msvC++中堆棧指針的最大值的最簡單估計的最快方法是什麼?使用C++,如何獲取msvc中堆棧指針的值X64

我打算用它來寫這個內聯函數:

static __forceinline bool IsOnStack(const void *p) { 
    return UINT_PTR(p) < __ESP; 
} 

我可以用它作爲一個宏

#define ISONSTACK(a) 

感謝,如果這是更好!

編輯

我需要知道,如果事情是在堆棧上的其他代碼不會釋放它。只需說出它是傳統的智能指針實現方式,我就可以加快速度。我必須處理的是智能指針所指對象的地址。我正在做一個改變,所以一個智能指針可以引用堆棧中的一個項目,這將消除堆棧分配過多。 64位堆棧看起來是一個相對較低的虛擬地址。我們的分配器使用預定義的虛擬基地址(現在是16GB)。我可以假設任何低於堆疊的東西。這個方法可能會意外地假定任何分配malloc或:: new的東西都在堆棧中,這不會是世界的盡頭,因爲我們不應該使用這些東西。我想我會看看是否有更好的方法來獲得堆棧所在的位置。只要我們沒有得到虛假的消極影響,性能比精確性更重要。

編輯

我知道我們目前只分配智能指針來分配內存,因爲我們只用2種方式來設置智能指針:

new(spFoo) CFoo(); // uses an overridden new to do this 

spFoo = spOtherFoo; 

我想添加:

CFoo Foo(); 
spFoo = &Foo; 

編輯 我應該補充一點,我們不使用std庫(部分原因是代碼太舊,部分原因是我們的應用程序是邊緣案例,性能非常重要)。我不想讓這個關於標準庫的爭論,我們都同意這很好。我沒有這個應用程序。我們的代碼僅在內部服務器上運行。我們的代碼全部是64位。有時我們使用線程,但這很少見。可移植性不是問題。我們使用microsoft visual studio 2013,它是vC++ 2012.我們在server 2008上運行。我們將在某一天升級到server 2012,並在Visual Studio 2015出現時升級。

這開始與通常抱怨內聯彙編不可用。然後,我很難找到有關在Windows上運行的vC++應用程序的常規內存佈局(堆棧,堆的位置等)的文檔。

+1

似乎解決方案的東西,你不應該需要......爲什麼你需要知道是否有東西在堆棧上? [換句話說,你可能會問一個XY問題] –

+0

在棧上聲明一個變量並取其地址。但是@MatsPetersson說你可能不需要知道這一點。 –

+0

我也很好奇,爲什麼你甚至需要做這樣的事情?另外,我不認爲這會做你認爲它會做的事。你能提供一個你的總體目標的例子嗎?也許是它的一個xy問題,我寧願在x中工作:) – ydobonebi

回答

0

好的,所以這會比「評論」的價值更長。

首先「知道你是否需要免費」,應該用std::shared_ptrstd::unique_ptr來解決,而不是「檢查它是否在堆棧上」。關於什麼:

void Function(int *p) 
{ 
    if (!isOnStack(p)) delete p; 
} 


std::vector<int> v; 

... fill stuff into v ... 
Function(&v[14]); 

中釋放的std::vector中間幾乎可以肯定是一個非常糟糕的事情 - 但我保證的地址不是在堆棧中。

static int x; 
Function(&x); 

那裏沒有更好 - 它也會造成不好的自由。關於「堆棧所在位置」完全基於運行時環境(OS和編譯器等的組合)。這可能是一個很高的地址。它可能是「主」線程中的高地址,而次線程中是低地址 - 但是您並不真的希望這隻能在「主」線程中工作,對嗎?

線程堆棧的位置當然也完全依賴於提供線程(和堆棧分配)的操作系統和運行時庫。

你可以做一些事情,如:

uintptr_t sp_base; 

bool isInStack(void *p) 
{ 
    int x; 
    uintptr_t sp_top = (uintptr_t)(&x); 
    // Assumes stack grows towards 0. 
    return (p > sp_top) && (p < sp_base); 
} 

int main() 
{ 
    int x; 
    sp_base = (uintptr_t)(&x); 
    ... 
} 

但它遠沒有保證每工作時間,甚至大部分的時間 - 這取決於實際的操作系統和編譯器的選擇,結果可能會有所不同相當瘋狂。

+0

謝謝。我們只使用visual studio編譯器,只能在windows上運行。我們的軟件僅供內部使用。與內存管理相關的功能被隔離在幾個類中,所以如果我們願意的話,我們可以輕鬆移植。性能是最重要的,所以一切都是自定義的。我們不使用標準庫。 64位編譯代碼似乎在內存中找到堆棧低位,緊跟在exe映像之後。堆在堆棧後立即返回地址。我的猜測是線程在堆上分配它們的堆棧,這是在相同的低內存位置。 – johnnycrash