6

我最近遇到了与堆损坏的第一场战斗 (已解决) 。在我家里的 linux 机器上,罪魁祸首代码使用 valgrind 和电栅栏(使用 gdb)没有错误地退出。然而,在我们实验室的 Windows 机器上,我一直从我引用的帖子中描述的 VS 中获得与堆损坏相关的错误消息。

valgrind 和电栅栏没有检测到这样的问题是否令人惊讶(或至少不常见)?其他人在此处的答案中提到了一个可能与 valgrind 相似的错误。这些工具无法检测到此问题的原因可能是什么?是否有任何理由怀疑错误实际上是堆损坏?

更新:正如描述原始问题的帖子中所述,我发现问题是由于指向 std::vector 中的元素的指针,这变得很糟糕。用 std::list 替换向量(添加新元素时指针不会变为无效)解决了这个问题。所以回到我关于为什么 valgrind 没有检测到问题的问题,我问是否有任何关于如何避免未来类似情况的建议,即 valgrind 没有检测到的内存问题,这是我的一个最喜欢的工具。显然,更好地了解 STL 的工作原理将是一个好主意。也许我需要在我的编程等中对断言更加自信。

4

3 回答 3

6

因此,Valgrind 未能检测到您的堆损坏的明显原因是 GCC STL 实现根本没有发生损坏(即没有检测到错误)。

不幸的是,Valgrind 的运行水平比 STL 低得多,因此仍有许多错误未被发现。例如:

std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.resize(0);
v[1] = 42;  // Oops. Out of bounds access, but Valgrind is silent

幸运的是,GCC STL 有一种特殊的调试模式,旨在捕捉许多此类问题。尝试使用-D_GLIBCXX_DEBUG. 它可能会捕捉到最初的问题,并且可能会捕捉到更多你还不知道的问题。

于 2011-04-27T04:16:12.693 回答
0

如果您使用相同的工具在一台机器上得到好的结果而在另一台机器上得到不好的结果,那么在开发机器上运行一些内存测试将是一个非常好的主意。可以轻松获得 memtest86 的可引导映像,并且某些内存错误可以巧妙地解释您的问题。

另一方面,如果您在每台机器上使用不同的操作系统,那么您使用的任何跨平台库的 Windows 版本中也可能(甚至更有可能)存在错误。

于 2011-04-25T03:05:47.170 回答
0

你不明白什么是堆损坏。特别是,内存泄漏不是堆损坏。

Parallel Studio 报告的内存泄漏也似乎是虚假的,并且更有可能是 Parallel Studio 中的错误而不是您的程序中的错误。

于 2011-04-25T03:38:14.490 回答