C++堆栈损坏

8

我有一段时间没有做C++了,但决定完成我为某人正在开发的一个大项目。然而,现在我遇到了以下错误信息...

检测到堆损坏: 在0x17DEB940处的Normal Block(#1761)之后。 CRT检测到应用程序在堆缓冲区结束后写入内存。

我已经逐步检查了我认为可能引起问题的所有函数,但是我束手无策。是否有使用更高级调试功能来追踪此问题的方法?


谢谢。哈哈,Linux、Mac和不可知论的答案先被发布的机会有多大呢? - Potatoswatter
你是否正在使用智能指针和C++容器模板类,还是这更像是一个带有类的C程序? - David Thornley
4个回答

4
这似乎是一个经典的内存损坏错误。平台信息会很有帮助。在没有看到您的代码及其复杂性之前,有几种可能性:
  1. 我猜运行时库可以让您直接从代码中添加堆验证代码。建议在代码的各个位置放置对堆验证代码的调用,以便确定出问题的位置。您将找到堆损坏的位置,并且知道在上一次调用时它是正常的。如果需要缩小窗口范围,请继续缩小,然后检查出问题的代码。
  2. 如果相同的步骤恰好在内存中损坏了完全相同的位置,则应该能够使用调试器在更改内存时设置断点(或监视点)。其中一些更改可能是有意的,但您应该能够确定哪个是罪魁祸首。
如果您的代码特别复杂或者重现此问题所需的步骤很长,请结合这两种方法:缩小有问题的代码段,然后在被损坏的内存位置上设置断点。

2
在Linux上,我建议使用valgrind作为一个工具来告诉你出了什么问题。你可以在这里寻找一些Windows的替代方案。

我之前在Windows上使用了Purify,效果很不错,但它是很贵的。 - Mark B

1

尝试使用工具来捕捉它。

听起来有点像经典的C语言错误。你确定你没有在while或for循环中写超出c数组(如int[xyz])的范围吗?这不会导致任何错误,但你会在许多与错误部分无关的空间中得到奇怪的效果。:p


1

尝试使用启用了正常页面堆的AppVerifier。然后将调试器附加到进程,并且如果有一些运气,当内存块被破坏(通过块写入溢出或下溢)时,它将在断点处中断。稍加努力,您还可以获得分配每个堆块的代码的调用堆栈,这也有助于跟踪错误。

尽管追踪这些错误可能会很棘手,但是有关详细信息,请查看《高级Windows调试》书籍,其中有一个专门讨论此主题的章节。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接