如何在C ++中检测未分配内存上的双删除或删除?

时间:2011-06-13 05:58:49

标签: c++ memory memory-leaks new-operator delete-operator

我正在编写全局删除/新运算符的调试版本,以检测内存泄漏,双重删除和删除未分配的内存。

就“new”运算符而言,我覆盖了全局新运算符并使用宏传递了文件名和行号信息。重写的“new”运算符将地址中的内存地址,文件名,大小和行号信息存储在地图中。

我也覆盖了“删除”操作符,从地图中删除了已删除的地址'条目。现在我想将删除的内存信息存储在另一个地图中,该地图存储了调用“删除”的文件名和行号信息。

但是delete运算符只接受参数(要删除的对象的内存地址)。 有人可以告诉如何检测代码中的双删除吗?

3 个答案:

答案 0 :(得分:6)

您已经在重载new内创建了已分配内存地址(键)和文件名,行号(值字段)的映射。

在重载删除时,只需检查您创建的地图中是否存在传递的地址。

如果是,您认为对delete的通话有效,并从地图中删除该地址条目。

如果否,则将删除调用视为有问题,delete called on a pointer not allocated through your newtrying to call delete multiple times

答案 1 :(得分:2)

如果你需要的是区分双删除和永久分配内存中的删除,只需将地址映射到已分配内存的 state ,而不是从地图中删除元素,只需更新 state 将其标记为已发布。每次删除中的测试将验证地址是否存在(如果不是错误正在删除从未分配的地址),如果是,则是否已经释放了内存(如果有,则错误是双重释放)。

答案 2 :(得分:0)

有两个不同的问题:检测双重删除(相反 删除从未分配的内存,并确定其中的位置 它发生的程序。 首先,我的调试operator new之前分配了保护区 然后它返回(也用于检测写过去的块) 以解除分配结束);我在operator delete中将它们设置为不同的模式,并检查此模式。总有机会 永远不会分配内存可能包含这种模式,但机会是 非常非常小。 确定错误发生在代码中的哪个位置更加困难。 我编写了一个堆栈回溯的代码,但它是非常系统的 依赖。 (我在Sparc上有Solaris版本,在Intel上有Linux版本,以及 Windows。)它报告的所有内容都是十六进制的返回地址;取决于 程序员使用其他工具分析这些工具。 GNU binutils package有一个程序addr2line,在Linux下运行良好,但是 考虑到有序地图,手动操作并不困难。

相关问题