• 如何判断一个C++对象是否在堆上(通过GetProcessHeaps取得所有堆,然后与对象地址比较即可),附许多精彩评论


    在帖子如何判断一个C++对象是否在堆栈上 中, 又有人提出如何判断一个C++对象是否在堆上。

    其实我们可以参照那个帖子的方法类似实现,我们知道堆就是Heap,在windows上我们可以通过GetProcessHeaps来得到所有的堆句柄,而我们这里只要知道Windows上的Heap Handle,其实就是堆的起始地址,就可以写如下代码了。

    #include <iostream>
    #include <windows.h>

    using namespace std;

    BOOL IsObjectOnHeap(LPVOID pObject)
    {
        BOOL bRet(FALSE);
        DWORD dwHeaps = GetProcessHeaps(0, NULL);
        LPHANDLE pHeaps = new HANDLE[dwHeaps];
        if(pHeaps != NULL)
        {
            MEMORY_BASIC_INFORMATION mi = {0};
            GetProcessHeaps(dwHeaps, pHeaps);

            for(INT i=0; i<dwHeaps; ++i)
            {
                VirtualQuery((LPVOID)pHeaps[i], &mi, sizeof(mi));
                
                if(pObject >= mi.BaseAddress 
                    && (DWORD)pObject < (DWORD)mi.BaseAddress + mi.RegionSize)
                {
                    bRet = TRUE;
                    break;
                }
            }
        }
        delete []pHeaps;

        return bRet;
    }

    int g_value = 10;

    int main(int argc, char* argv[])
    {
        int nStackValue = 1;
        int* pNew = new int(10);
        int* pNewArray = new int[100];

        static int static_value = 0;
        
        cout << "g_value:" << IsObjectOnHeap(&g_value) << endl;  //false
        cout << "nStackValue:" << IsObjectOnHeap(&nStackValue) << endl;   //false
        cout << "static_value:" << IsObjectOnHeap(&static_value) << endl;    //false
        cout << "pNew:" << IsObjectOnHeap(pNew) << endl;        //true
        cout << "pNewArray:" << IsObjectOnHeap(pNewArray) << endl;    //true

        system("pause");
        return 0;
    }
    以上代码在Windows下测试通过(也只能在Windows上跑),如果有不正确的地方,欢迎指正。

    注: 上面关于对象是否在堆上的判断应该是不对,因为堆内存不是连续内存,内部是通过类似链表的结构来实现的,<<软件调试>>里有相关介绍,也可以通过WinDbg的 !address 命令查看内存分布

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

    其实判断一个对象是在堆上还是在栈上根本不必这么复杂,因为,系统默认栈地址是固定的,栈空间最多长到1MB,若超过1MB会引发栈耗尽异常,所以只需判断是否在栈上,就只是看看有没有在这个地址区间内

  • 相关阅读:
    几篇操作Excel的文章资源
    [转]Oracle用一个表的列更新另一个表对应记录的列
    【转】Earth Viewers几个三维地球软件比较
    在ArcGIS Server中如何定义“此级别无数据”图片?的终极解决方案
    [转]ODAC 应用技巧 (一)使用 ODAC 的 Net 方式
    Centos7 ipset命令介绍及使用
    在线编辑Word——插入图表 E
    Java 在PPT中创建散点图 E
    yum问题Cannot retrieve metalink for repository: epel/x86_64. Please verify its path and try again
    Base64和urlencode
  • 原文地址:https://www.cnblogs.com/findumars/p/5789450.html
Copyright © 2020-2023  润新知