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

How to detect double deletes or deletes on unallocated memory in C++?

本文关键字:删除 内存 分配 C++ 检测      更新时间:2023-10-16

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

就"new"操作符而言,我覆盖了全局new操作符,并使用宏传递了文件名和行号信息。被覆盖的"new"操作符将内存地址、文件名、大小和行号信息存储在键入地址的映射中。

我也重写了"delete"操作符,它从映射中删除了已删除的地址条目。现在我想将删除的内存信息存储在另一个映射中,该映射存储调用"delete"的文件名和行号信息。

但是delete操作符只接受参数(要删除的对象的内存地址)。有人能告诉我们如何检测代码中的双重删除吗?

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

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

如果是,则认为对delete的调用有效,并从地图中删除该地址条目。

如果否,则认为要删除的调用有故障,即delete called on a pointer not allocated through your newtrying to call delete multiple times

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

有两个独立的问题:检测双重删除(与删除从未分配的内存,并确定在发生的程序。对于第一个,我的调试operator new在并且在块之后它返回(也用于检测通过解除分配结束);我在operator delete中将它们设置为不同的模式,并检查此模式。总有可能从未分配的内存可能包含这种模式,但有可能非常非常小。更难确定错误发生在代码中的哪个位置。我写了一些代码,可以进行堆栈回溯,但这是非常系统的依靠的(我有Sparc上的Solaris版本、Intel上的Linux版本,以及Windows。)它所报告的只是十六进制的返回地址;这取决于程序员使用其他工具来分析这些。GNU二进制工具该包有一个程序addr2line,它在Linux下运行良好,但是如果有一个排序的地图,手动操作并没有那么困难。