堆腐败:原因是什么?

Sat*_*bir 19 c++ memory-management

我正在调查由于堆损坏导致的崩溃.由于这个问题非常重要并涉及分析堆栈和转储结果,因此我决定对与崩溃相关的文件进行代码审查.

坦率地说,我没有深入了解何时堆可能被破坏.

如果你能提出可能导致堆损坏的情况,我将不胜感激.

平台:Windows XP

语言:C++

编译器:VC6

cwa*_*wap 38

常见方案包括:

  • 在数组的分配空间外写(char *stuff = new char[10]; stuff[10] = 3;)
  • 投射到错误的类型
  • 未初始化的指针
  • 错误 - >和.
  • 使用*和&(或其中之一的多个)时出现错字错误

[编辑]从评论中,还有一些:

  • 将new []和new与delete []混合并删除
  • 缺少或不正确的拷贝构造函数
  • 指向垃圾的指针
  • 在同一数据上多次调用delete
  • 没有虚拟析构函数的多态基类


Coi*_*oin 13

欢迎来到地狱.没有简单的解决方案,所以我只提供一些指示.

尝试重现调试环境中的错误.调试器可以使用绑定检查填充堆分配,并告诉您是否在这些绑定检查中编写.此外,它将使用相同的虚拟地址一致地分配内存,从而使再现性更容易.

在这种情况下,您可以尝试使用Purify等分析工具.他们会检测到你的代码正在做的任何令人讨厌的事情,但也会非常缓慢地运行.这样的工具将检测超出范围的内存访问,释放内存访问,尝试释放两次相同的块,使用错误的分配器/解除分配器等...这些都是可以保持潜伏很长时间而且只是崩溃的所有条件在最不合时宜的时刻.

  • 我明白。然而,即使该错误表现为百万分之一的崩溃,它仍然可以很容易地被分析工具检测到。 (2认同)
  • 确实,"欢迎来到地狱". (2认同)

Kom*_*mat 6

您可以从" 高级Windows调试"一书中查看示例章节,其中提供了堆损坏的各种示例.

编辑:如果您正在使用可能在更改期间移动元素的stl容器(即vector,deque),请确保您不会在可能更改它的操作中保留对这些元素的引用.


Dav*_*ley 6

有些产品会观察内存分配和解除分配,并生成异常报告.最后我用了一个,它们并不便宜,但我不知道现在情况如何.但是,找到VC++ 6的东西可能是个问题.

请记住,您可能比崩溃更容易导致堆损坏,因此请注意问题报告,并修复所有堆损坏.

我建议std::tr1::smart_ptr<>在任何地方使用而不是原始指针,但我不确定VC++ 6是否会支持它.

你为什么还在使用VC++ 6?升级是否可行?使用更新版本的工具更好,并且它们完全支持智能指针.