zoukankan      html  css  js  c++  java
  • 如何判断一个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

  • 相关阅读:
    Spring Cloud 五 Feign的文件上传实现
    Spring Cloud 四:服务消费(Feign)【Dalston版】
    Spring Cloud 三:服务消费(Ribbon)【Dalston版】
    Spring Cloud二:服务消费(基础)【Dalston版】
    Spring Cloud 一:服务注册与发现(Eureka)【Dalston版】
    mybatis 单个参数
    医院设置(图论Floyd)
    Mysql学习——安装登录
    字母游戏(搜索)
    子数列连续和
  • 原文地址:https://www.cnblogs.com/findumars/p/5789455.html
Copyright © 2011-2022 走看看