如何在C++中调试双删除?

Gen*_*ent 11 c++ debugging memory-management

我正在维护用C++编写的遗留应用程序.它时不时地崩溃,Valgrind告诉我它是对某个对象的双重删除.

找到导致您不完全理解的应用程序中的双重删除以及哪个太大而无法重写的错误的最佳方法是什么?

请分享您最好的提示和技巧!

Ogr*_*m33 4

以下是一些在这种情况下对我有帮助的一般建议:

  1. 如果您使用记录器,请将日志记录级别调高至完全调试。在输出中查找可疑内容。如果您的应用程序不记录可疑对象/类的指针分配和删除,则需要cout << "class Foo constructed, ptr= " << this << endl;在代码(以及相应的delete/析构函数打印)中插入一些语句。
  2. 使用 --db-attach=yes 运行 valgrind。我发现这非常方便,尽管有点乏味。每次检测到重大内存错误或事件时,Valgrind 都会向您显示堆栈跟踪,然后询问您是否要调试它。如果您的应用程序很大,您可能会发现自己重复按“n”多次,但请继续查找首先(第二次)删除相关对象的代码行。
  3. 直接扫一下代码就可以了 查找相关对象的构造/删除。可悲的是,有时它最终会出现在第三方库中:-(。
  4. 更新:最近刚刚发现:显然 gcc 4.8 及更高版本(如果您可以在系统上使用 GCC)有一些新的内置功能用于检测内存错误,即“地址清理器”。也可在LLVM 编译系统中使用。

  • 作为第 3 点的附录。如果您要将对象的指针分配给其他对象(即使是暂时的),您可能还需要查找赋值操作 `Thing* thisThing = otherThing`,并删除它们中的任何一个,然后删除对象从记忆中,任何访问、修改或删除其他内容的尝试都会导致问题。 (2认同)