错误:HEAP CORRUPTION DELECTED

来源:互联网 发布:淘宝网 服务中心 编辑:程序博客网 时间:2024/05/29 16:13



2011-09-08 16:34:45|  分类: 默认分类 |字号 订阅
今天在VS2010调试项目中出现的问题,通过调用free出现了这个错误。一般VC的HEAP CORRUPTION DETECTED这类错误只有在开发的DEBUG版本上出现,Realse版本可能看不到这个错误,有时甚至软件程序还能正常运行,但是千万不能被表象所蒙蔽,随着时间的流逝,程序会因为一些莫名其妙的问题而崩溃,所以在Debug版本上出现这个问题是有其道理的,这里无非是对内存的操作出现了问题,内存经典的操作就是通过调用malloc申请内存,以及调用free释放内存,微软在调试模式下帮我们修改了这两个函数,特别是malloc多分配了一些空间,这些空间就是用于检测内存泄漏(Memory Leaks)和内存损坏(Memory damage)等一系列问题的。所以一旦出现这些问题,Debug版本下能立刻反应过来,告知HEAP CORRUPTION DETECTED以及详细原因并中止程序执行。不过我们如果点击调试,VC将跟踪到SDK的malloc实现中去,不是我们自己的程序问题点,这是比较头疼的地方。


首先出现内存泄漏,一般是内存泄漏不会出现这么明显的中断,所以判断是否因为分配内存损坏的原因,经典的是“野指针”问题,因为free释放指针指定的空间后不能置空指针,所以该指针就变成了野指针,其所指向的地址不是我们所期望的,如果这个时候调用free将造成内存损坏,Realse模式下可能会导致程序异常中止,Debug模式下就会出现HEAP CORRUPTION DETECTED的错误。


鉴于此我检查了代码,并没有找到类似问题,这时我的注意力集中在下面图片指示的一段文字上:






“CRT detected that the application wrote to memory after end of heap buffer”,意思是C运行时(CRT)检测到应用程序写入了堆缓冲的结尾。基本上可以判断是由于调用malloc分配了空间后,对于这段空间操作不当所造成的。仔细检查了代码,发现了memset,好家伙这么重要的内存操作函数怎么忘了,事实证明,问题确实由memset所致,因为利用memset清0的空间大小比实际空间大小在控制判断时多处理了一点,就是因为这点大小导致了堆损坏,这个问题一直到free才被detect出来,看来Bug隐藏还是比较深的,从另外一个方面讲我们要重视Debug模式下的任何警告消息。


 


 


以上观点是我从网上找到的,但是这个问题在我的程序中出现的地方很诡异。网上找到的这些解决方法,和我想到的是一样的,我使用以上方法根本解决不了问题。写此博客,就是希望大家少走弯路,也告诫自己。


首先,这个问题的原因,肯定是指针造成的。C++中使用指针,出现这种情况的概率很大。我自己编写了一个DLL库,在库的DOS测试程序下没有任何问题,当将库一直到MFC stander单文档中也没有问题。当将库移到MFC VS2005风格单文档就出现了这样的问题。原因肯定是指针在NEW和DELETE的过程中。


在此,找到原因后进行排查。因为我不同于惯见的解决方法。我仅仅在单文档中申请一个我的库中的一个对象指针,然后使用它,并DELETE他时出现这个问题。


起先,我害怕是在库中的对象使用了多态,造成NEW的实际对象要比基类大而造成的,但是修改之后并没有改变任何运行结果。


在此,因为将库强制输出成C的格式造成的,结果也不是。


最后,排查每一个指针也不存在问题。


那那里存在问题呢。当排查完指针后,错误有所改变,变成了LIST什么什么的,指向了LIST头文件。因为我在库中使用了STL表LIST.检查LIST使用还是没有问题。


解决,最终我发现我的某个对象中还有其他对象的指针,这个指针没有给他初始化。在使用它的时候没有对她进行非空判断。可能是这里的问题,所以我在使用它的时候给他加上了非空的判断,另外给他初始化为0。


再次运行发现错误解决了。


总结:以上问题是很痛苦的一个异常。问题的根源很难找到,原因很简单,就是野指针的出现。要解决上面问题,需要有足够的耐心慢慢排查。为了避免上面的问题,很简单,就是你的代码要规范,按照C++语法要求,变量必须先定义,然后初始化,最后才可以使用,另外在使用指针时,加上判断。  
原创粉丝点击