检测动态分配的对象?

时间:2011-09-15 16:14:37

标签: c++ memory-management

我可以检查一个对象(通过指针或引用传递)是否是动态分配的?

示例:

T t;
T* pt = new T();
is_tmp(&t); // false
is_tmp(pt); // true

上下文

我完全意识到这有点像糟糕的设计,事实上它是,但我试图扩展代码我不能(或应该不)修改(当然我责怪代码不是我的;))。它调用一个方法(我可以覆盖),它将delete传递的对象以及仅适用于动态分配的对象的其他东西。现在,我想检查一下我是否有一些可以delete d或者是暂时的。

我永远不会传递一个全局(或静态)变量,所以我在这里保留这个未定义的。

5 个答案:

答案 0 :(得分:4)

不便携。在PC上的Solaris或Linux下(至少32位Linux), 堆栈位于可用内存的最顶层,因此您可以比较它 传入本地变量地址的地址:如果是地址 传入的高于局部变量的对象,它的对象 指向是局部变量或临时变量,或者是一部分 局部变量或临时变量。但是,这种技术会调用undefined 行为左右 - 它恰好适用于两者 我提到的平台(并且可能适用于所有平台 堆栈位于可用内存的顶部并逐渐减少。)

FWIW:您还可以检查这些机器上的静态。所有的静力学都是 在内存的底部,链接器在符号处插入符号end 他们结束了。因此,使用此名称声明外部数据(任何类型), 并将地址与之比较。

关于可能删除对象,但是......只是知道 对象不在堆上(也不是静态)是不够的。该 object可能是更大的动态分配对象的成员。

答案 1 :(得分:2)

一般来说,正如DeadMG所说的那样,你无法从它指向的指针中辨别出来。但是,作为调试或移植或分析措施,您可以向您的类中添加一个跟踪动态分配的成员operator new(前提是没有人使用显式全局::new - 包括容器,我担心)。然后,您可以构建set<T*>动态分配的内存并在那里进行搜索。

这根本不适用于任何严肃的应用程序,但也许这可以帮助您跟踪事物的来源。您甚至可以向运营商添加带行号的调试消息。

答案 2 :(得分:0)

不,不可能知道。你应该修复bug。在最少的情况下,您可以使用智能指针(如shared_ptr),如果您不希望删除它,则为其提供一个空的自定义析构函数。

答案 3 :(得分:0)

如果您可以访问动态内存分配器代码本身,则可以扫描内部结构并查看当前指针是否在其分配的列表/堆栈/区域中,或者是否存储它。通常它们存储为链表样式结构,扫描var的地址并不难。

答案 4 :(得分:0)

在我看来应该是可能的 因为您可以检查内存是在堆上还是堆栈上 这将是高度依赖平台的代码

首先你必须得到堆的范围,然后你必须检查传递的内存地址是否在这个范围内...
(听起来很简单,但第一步可能很棘手:-))