前段时间接手的项目中有出现HEAP: Free Heap block XXX modified at YYY after it was freed问题,作为C/C++程序员,如果代码写得不规范,出现这样的问题就不足为奇了。出现这样问题的根本原因就是野指针,即:对已经释放了的内存进行写操作。如:
int* p = new int;
int* pp = p;
delete p;
*pp = 1; //野指针赋值
在野指针赋值后,如果下次内存分配时,分配到上pp所指地址段,在DEBUG版本调试时,就会在VS的输出窗口出现Free Heap block XXX modified at YYY after it was freed提示。
出现这样的提示说明代码内存操作有问题,但是不好定位是哪个指针出现了问题。网上很少有真正能解决这样问题的方案,有说使用GFlags,但是它对大项目的支持是相当不足的,因为使用它会额外占用相当多的内存,如果内存不是很宽裕,会导致程序运行非常慢,甚至无法正常工作。btw,我第一次使用它时,由于不熟悉使用方法,直接导致系统所有程序无法开启,系统无响应,无法正常启动系统等等一系列问题,如果不幸你也出现了这样的问题,那请进入安全模式启动系统,使用GFlags把设置改回来即可。
其实,我们完全可以自己写代码解决这个问题。根据问题,我们知道是因为已经释放了的指针地址(野指针)所在的内容被改变,那么只要我们在释放的内存的时候把地址记录下来,在出现这样问题的时候,从记录中去查找就可以了。
具体步骤如下:
1.重载new操作符,在new操作中记录下内存分配时的相关信息,最重要的是文件名和文件所在行,方便后面出问题时的查找定位。
2.重载delete操作符,在delete操作中记录下已经释放的内存块信息。
3.写一个可以根据地址查找内存块信息的函数。
经过上面的工作,我们就可以在出现问题时直接定位到引起问题的地方了。
实现后,我写了一个简单的测试示例:
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
int* p = new int;
int* pp = p;
delete p;
*pp = 1;
p = new int;
delete p;
return 0;
}
调试运行时,出现
HEAP[test.exe]: HEAP: Free Heap block 5ed6d8 modified at 5ed71c after it was freed
test.exe 已触发了一个断点
只需要把上面的5ed71c在监视窗口中传入我写的FindBlock函数中就可以看到出现问题所在的文件行了,如下图所示: