检测动态分配的对象

Detect dynamically allocated object?

本文关键字:对象 动态分配 检测      更新时间:2023-10-16

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

的例子:

T t;
T* pt = new T();
is_tmp(&t); // false
is_tmp(pt); // true
<<h3>上下文/h3>

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

我永远不会传递一个全局(或静态)变量,所以这里我没有定义

不可移植。PC上的Solaris或Linux(至少32位Linux)堆栈位于可用内存的最顶端,因此您可以比较传递给局部变量地址的地址:如果地址传入的值高于局部变量的值,即对象的值指向的是局部变量或临时变量,或者是类的一部分局部变量或临时变量。然而,这种技术调用了undefined右边和左边的行为,它恰好对这两个都有效我提到的平台(并且可能会在所有的平台上运行)栈位于可用内存的顶部,并逐渐减少)。

fww:你也可以检查这些机器上的静态数据。所有的静态数据都是在内存的底部,连接器插入符号end在结束了。所以用这个名字声明一个外部数据(任何类型),并与之比较地址

关于可能删除的对象,然而…仅仅知道对象不在堆上(也不是静态的)是不够的。的对象可以是更大的动态分配对象的成员。

一般来说,正如DeadMG所说,您无法从指针中判断它来自何处。然而,作为一种调试、移植或分析措施,您可以将成员operator new添加到跟踪动态分配的类中(前提是没有人使用显式全局::new——恐怕包括容器)。然后,你可以建立一个动态分配内存的set<T*>,并在其中进行搜索。

这并不适合任何严肃的应用程序,但也许这可以帮助您跟踪事物的来源。您甚至可以在操作符中添加带有行号的调试消息。

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

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

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

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