开发过程中,有时候会遇到堆异常的情况
这时,VS的调试输出窗口会提示:
HEAP[MemTest.exe]: HEAP: Free Heap block 39b998 modified at 39b9c0 after it was freed
Windows has triggered a breakpoint in MemTest.exe.
This may be due to a corruption of the heap, which indicates a bug in MemTest.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while MemTest.exe has focus.
The output window may have more diagnostic information.
就是说已经释放的堆内存被修改了,一般就是new/malloc 后的内存,在被delete/free后又被使用了
一个简单例子
VC2008编译运行以上程序(DEBUG模式),发现运行到void test(void)函数的new那条语句时程序报错
不过这个new是不应该报此错误的,顶多报个内存不足就够了......郁闷啊,后来发现,对内存被释放后再使用是不会立即报错的,等到再次使用堆操作函数时才会报错。
也就是说,当时的调用堆栈是不准确的,那定位真正出问题的地方才是关键。
在MSDN论坛上有人说可以观察memory窗口,根据内存内容推测问题。运气好的话在报错的内存地址处可以看出来蛛丝马迹(比如说上面的实验程序),运气不好就只好把申请的内存和使用的地方全部打印。
Free Heap block AAAA modified at BBBB after it was freed在这句提示里,block AAAA 不是平时申请地址后的返回值,一般都比我们申请的小一些,在VC2008 DEBUG的模式下这个值比申请出来的小40(0x28)的字节, 地址 BBBB 应该总是不小于 AAAA。
这种问题不好调试,貌似网上也没什么有效的方法,
参考:
内存窗口的使用(http://social.msdn.microsoft.com/Forums/hu-HU/vclanguage/thread/01bae812-0a5f-4b17-9745-b1c8293a25b1)
再次申请或退出时报错(http://hi.baidu.com/lcs0000824/blog/item/9e77e4a58ef2e1ff9152ee7e.html/cmtid/783c8809d62fc19e0a7b8211)
此时堆栈不准确(http://www.davekb.com/browse_programming_tips:free_heap_block_modified_after_it_was_freed:txt)