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

发布于 11-15 00:51 字数 274 浏览 4 评论 0原文

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

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

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

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

I'm writing a debug versions of global delete/new operator to detect memory leaks, double deletes and delete on unallocated memory.

As far as "new" operator is concerned, I overrode the global new operator and using macros I passed file name and line number information. The overridden "new" operator stores the memory address, file name, size and line number information in map keyed on address.

I overrode "delete" operator too, which removes the deleted address' entry from the map. Now i want to store the deleted memory information in another map which stores the file name and line number information from where the "delete" was called.

But the delete operator takes only argument (memory address of the object to be deleted).
Can someone tell how to detect double deletes in the code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

看轻我的陪伴2024-11-22 00:51:47

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

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

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

如果否,则将删除调用视为错误,在未通过 new 分配的指针上调用删除尝试多次调用删除

You are already creating a map of allocated memory addresses(key) and filename, line number(value fields) inside your overloaded new.

While in your overloaded delete just check if the address being passed exists in the map you created.

If Yes, You consider the call to delete as valid and remove that address entry from your map.

If No, then consider the call to delete as faulty, delete called on a pointer not allocated through your new or trying to call delete multiple times.

错々过的事2024-11-22 00:51:47

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

If what you need is to differentiate a double delete from a delete from a never allocated memory, just map addresses to state of the allocated memory, instead of removing the element from the map, just update the state to mark it as already released. The test in each delete would verify if the address is present (if not the error is deleting a never allocated address), and if so, whether the memory has already been released (if it has, then the error is a double free).

红尘作伴2024-11-22 00:51:47

有两个单独的问题:检测双重删除(而不是
删除从未分配的内存,并确定在哪里
它发生的程序。
首先,我的调试 operator new 在之前分配了保护区
在块返回之后(也用于检测超过该块的写入)
结束分配);我在 operator 中将它们设置为不同的模式
删除
,并检查此模式。总有这样的机会
从未分配的内存可能包含此模式,但机会是
非常非常小。
确定代码中发生错误的位置更加困难。
我已经编写了执行堆栈回溯的代码,但它非常系统
依赖。 (我有 Sparc 上的 Solaris、Intel 上的 Linux 以及
Windows。)它报告的只是十六进制的返回地址;这取决于
程序员使用其他工具来分析这些。 GNU binutils
软件包中有一个程序addr2line,它在Linux下运行良好,但是
给定一个排序的地图,手动完成并不困难。

There are two separate issues: detecting the double delete (as opposed
to a delete of memory that was never allocated, and determining where in
the program it occurred.
For the first, my debugging operator new allocates guard zones before
and after the block it returns (also used for detecting writes past the
end on deallocation); I set them to a different pattern in operator
delete
, and check for this pattern. There's always the chance that
never allocated memory might contain this pattern, but the chance is
very, very small.
Determining where in the code the error occurred is more difficult.
I've written code which does a stack walkback, but it's very system
dependent. (I have versions for Solaris on Sparc, Linux on Intel, and
Windows.) And all it reports is the return addresses in hex; it's up to
the programmer to analyse those, using other tools. The GNU binutils
package has a program addr2line, which works well under Linux, but
it's not that difficult to do manually, given a sorted map.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文