如何判斷一個C++對象是否在堆棧上(通過VirtualQuery這個API來獲取堆棧的起始地址,然后就可以得到答案了),附許多精彩評論


 

昨天有人在QQ群里問到如何判斷一個C++對象是否在堆棧上, 我在網上搜索了下, 搜到這個么一個CSDN的帖子http://topic.csdn.net/t/20060124/10/4532966.html ,可惜它也沒有給出一個合適的答案。

要解答這個問題,其實就是要知道的堆棧的起始地址, 而我們知道堆棧其實就是一段有相同屬性的內存頁面,而Windows也是有API讓我們查詢虛擬內存的頁面分配情況的。所有我們可以通過VirtualQuery這個API來獲取堆棧的起始地址,然后就可以得到答案了。

BOOL IsObjectOnStack(LPVOID pObject)
{
    INT nStackValue(0);

    MEMORY_BASIC_INFORMATION mi = {0};
    DWORD dwRet = VirtualQuery(&nStackValue, &mi, sizeof(mi));

    if(dwRet > 0)
    {
        return pObject >= mi.BaseAddress 
            && (DWORD)pObject < (DWORD)mi.BaseAddress + mi.RegionSize;
    }

    return FALSE;
}

int g_value = 10;

int main(int argc, char* argv[])
{
    int nStackValue = 1;
    int* p = new int(10);
    
    BOOL bStackValue = IsObjectOnStack(&g_value);  //false
        bStackValue = IsObjectOnStack(&nStackValue); //true
        bStackValue = IsObjectOnStack(p); //false

    system("pause");

    return 0;
}


當然,我們知道每個線程都有自己的堆棧,所以上面的方法針對線程1查詢線程1的堆棧對象是可行的,線程2查詢線程2的堆棧對象頁是可行的,但是線程1查詢線程2的堆棧對象就不行了。所以多線程情況下,我們可以統計出所有的線程堆棧起始地址,然后統一判斷。當然隨着線程的建立和銷毀,堆棧本身也是在不斷變化的。

我想了下,不知道判斷對象是否在堆棧上在我們實際編程中有什么用,誰知道的話麻煩提示下。

以上代碼在Windows下測試通過,如果有不正確的地方,歡迎指正。

http://www.cppblog.com/weiym/archive/2012/05/12/174634.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM