簡體   English   中英

使用C ++,如何在msvc X64中獲取堆棧指針的值

[英]Using c++, how do I get the value of the stack pointer in msvc X64

使用C ++,在X64上的msvc ++中,獲取堆棧指針或對堆棧指針的最大值進行粗略估計的最快方法是什么?

我將使用它來編寫此INLINE函數:

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

如果更好的話,我可以將其用作宏

#define ISONSTACK(a)

謝謝!

編輯

我需要知道棧中是否有東西,以便其他代碼不會釋放它。 可以肯定地說,它是我正在更快地實現的智能指針的傳統實現。 我需要處理的只是智能指針所指對象的地址。 我正在進行更改,以便智能指針可以引用堆棧上的項目,這將消除多余的堆分配。 64位堆棧似乎是一個相對較低的虛擬地址。 我們的分配器使用預定義的虛擬基地址(現在為16GB)。 我可以假設任何低於堆棧的內容。 該方法可能會意外地假設使用malloc或:: new分配的任何東西都在堆棧上,這不會是世界末日,因為我們不應該使用它們。 我想我會看看是否有更好的方法來了解堆棧在哪里。 只要我們沒有誤報,性能就比准確性更重要。

編輯

我知道我們目前僅將智能指針分配給已分配的內存,因為我們僅使用兩種方式來設置智能指針:

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

要么

spFoo = spOtherFoo;  

我正在考慮添加:

CFoo Foo();
spFoo = &Foo;

編輯我應該補充一點,我們不使用std庫(部分是因為代碼太舊了,部分是因為我們的應用程序處於極端情況並且性能如此重要)。 我不想就標准庫進行辯論,我們都認為這很棒。 我沒有此應用程序。 我們的代碼僅在內部服務器上運行。 我們的代碼都是64位。 有時我們使用線程,但這很少見。 可移植性不是問題。 我們使用的是Microsoft Visual Studio 2013,即vc ++2012。我們在服務器2008上運行。有一天我們將升級到服務器2012,而在Visual Studio 2015發布時將升級到服務器。

這始於通常沒有關於內聯匯編的抱怨。 然后,我很難找到有關在Windows上運行的vc ++應用程序的常規內存布局(堆棧在哪里,堆棧在哪里等)的文檔。

好的,所以這將比“評論”值長。

首先,“知道是否需要釋放”應該用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和編譯器的組合等)。 它可能是一個高位地址。 它可能在“主”線程中是一個高地址,而在輔助線程中可能是一個低地址-但您並不是真的希望它僅在“主”線程中起作用,對嗎?

當然,線程堆棧的位置還完全取決於提供線程(以及堆棧分配)的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); 
    ... 
}

但是,它並不能保證每次甚至在大多數時間都能正常工作-根據實際的操作系統和編譯器選擇,結果可能會有很大的不同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM