昨天有人在QQ群里問到如何判斷一個(gè)C++對(duì)象是否在堆棧上, 我在網(wǎng)上搜索了下, 搜到這個(gè)么一個(gè)CSDN的帖子
http://topic.csdn.net/t/20060124/10/4532966.html ,可惜它也沒有給出一個(gè)合適的答案。
要解答這個(gè)問題,其實(shí)就是要知道的堆棧的起始地址, 而我們知道堆棧其實(shí)就是一段有相同屬性的內(nèi)存頁(yè)面,而Windows也是有API讓我們查詢虛擬內(nèi)存的頁(yè)面分配情況的。所有我們可以通過VirtualQuery這個(gè)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;
}
當(dāng)然,我們知道每個(gè)線程都有自己的堆棧,所以上面的方法針對(duì)線程1查詢線程1的堆棧對(duì)象是可行的,線程2查詢線程2的堆棧對(duì)象頁(yè)是可行的,但是線程1查詢線程2的堆棧對(duì)象就不行了。所以多線程情況下,我們可以統(tǒng)計(jì)出所有的線程堆棧起始地址,然后統(tǒng)一判斷。當(dāng)然隨著線程的建立和銷毀,堆棧本身也是在不斷變化的。
我想了下,不知道判斷對(duì)象是否在堆棧上在我們實(shí)際編程中有什么用,誰(shuí)知道的話麻煩提示下。
以上代碼在Windows下測(cè)試通過,如果有不正確的地方,歡迎指正。
posted on 2012-05-12 10:57
Richard Wei 閱讀(5674)
評(píng)論(9) 編輯 收藏 引用 所屬分類:
C++