1

啊! 我想我有其中一个晦涩的记忆错误。但我不确定。它甚至可能不在我的代码部分。我正在 MS VC++ 2005 上测试一个(C++)应用程序。现在,我的代码在看似无害的向量推回时抛出了一个异常并由于一些堆错误而中断:

std::vector<int> blah;
for(int i=0; i<somesize; ++i) {
   blah.push_back(0);
}

无论我将这段代码移动到哪里,失败都发生在推回时。这太疯狂了!我确信这种用法没有任何违法之处。此外,当我将其注释掉时,它会毫无问题地通过它。在它的上方和下方,我有其他向量,我可以毫无问题地加载它们。与此相关,我还有另一个关于这样做的问题:

std::vector<double*> wha;
wha.push_back(nil);
..
... 
wha[0] = some pointer I create;

我的问题是:当 wha 超出范围时,它不应该删除指针,对吗?我想我是对的,但最好澄清一下。很抱歉,没有太多细节,但如果有任何其他细节有帮助,请告诉我,我会尝试发布更多信息。谢谢。

编辑:

确切的错误信息是:

First-chance exception at 0x771b70cd in myprogram_run.exe: Microsoft C++ exception: 
H5::FileIException at memory location 0x08026ca0..
First-chance exception at 0x771b70cd in myprogram_run.exe: Microsoft C++ exception: 
H5::FileIException at memory location 0x08026ca0..
'myprogram_run.exe': Loaded 'C:\Windows\System32\wdmaud.drv', No symbols loaded.
...
...
''myprogram_run.exe': Unloaded '<path\to>\bin\win64-x64-vs2005.shared\tcl85.dll'
The thread 'Win64 Thread' (0x23a8) has exited with code 0 (0x0).
The thread 'Win64 Thread' (0x120c) has exited with code -1 (0xffffffff).
The thread 'Win64 Thread' (0x27bc) has exited with code -1 (0xffffffff).
...
...
HEAP[myprogram_run.exe]: HEAP: Free Heap block dfd6870 modified at dfd68d0 after it was freed
Windows has triggered a breakpoint in myprogram_run.exe.

This may be due to a corruption of the heap, and indicates a bug in myprogram_run.exe or any of 
the DLLs it has loaded.

The output window may have more diagnostic information 
The program '[3052] myprogram_run.exe: Native' has exited with code -1 (0xffffffff).

我应该担心 H5::FileIExceptions 吗?我们确实将它作为第 3 方 DLL 链接。

4

2 回答 2

3
  1. 您发布的代码很好。内存损坏可能发生在其他地方,push_back只是揭示了它。
  2. nil不会被删除。每次使用 时push_back,都会将指针的副本推入向量中。唯一被删除的是包含所有指针副本的内部数组。
于 2012-06-12T17:02:09.590 回答
1

一般来说,遇到堆损坏时你应该做的第一件事是启用某种形式的“调试 malloc”,大多数平台都有这个。

在 VC++2005 上,显然你可以#define _DEBUG. 这会将 malloc() 转换为_malloc_dbg(),其中包括调试信息(例如文件/行)和填充以检查缓冲区溢出/不足。另请参见CRT 调试堆

编辑:如果这没有帮助(而且通常没有帮助),您可以使用调试 malloc 在每次分配后放置一个“保护页”,例如DUMA或 OSX 的libgmalloc. 这在调试版本中默认不启用,因为开销很大(每次分配最多约 8K),但可以更快地调试问题并捕获错误访问,而不是随后调用 malloc()/free()/堆检查功能)。

(我最近修复了一个我已经忍受了多年的〜每周崩溃- 可能超过十年!我不确定我之前怎么没有想到这样做,因为我已经知道 libgmalloc几乎一样长的时间,并用它来调试工作中的堆损坏。)

于 2012-06-12T18:27:40.420 回答