加载中…
个人资料
南冠彤
南冠彤
  • 博客等级:
  • 博客积分:0
  • 博客访问:415,028
  • 关注人气:59
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
相关博文
推荐博文
谁看过这篇博文
加载中…
正文 字体大小:

(转)C++笔记——Delete时堆错误(Heap Corruption)的原因

(2012-12-28 16:09:05)
标签:

杂谈

分类: CPP/C
最近这三四天一直在跟一个bug做斗争:程序在运行过程中死掉,Output窗口显示:

        1.Windows has triggered a breakpoint in ***, This may be due to a corruption of the heap...

        2.Access violation reading location...

        今天下午终于找到了真正的原因。那也就顺便把关于这个问题Google到的知识总结一下:

        

        这些问题均有可能代表程序中出现了堆错误。

        而出现堆错误的原因主要有 以下两大类:


        首先是工程设置方面的问题:

        1.在dll中申请的内存(new)在exe中释放了(delete),这时有可能会报堆错误;这时需要在dll中导出一个用于释放内存的函数;

        2.在一个dll中申请的内存,在另一个dll中释放;而这两个dll使用的运行时库不同。这时可以如1一样确保哪个模块申请的内存就在那个模块释放,也可以将两个工程的运行时库设置成同一个,即MD(d)或者MT(d);


        第二类是代码逻辑中的问题:

        1.同一块地址的指针被释放(delete)了两次,会导致以上错误。一般地,在每次释放内存之后,都将相应指针设置为NULL,并在delete指针之前进行检查,可以避免这种问题;

        2.内存申请之后,又对相应指针进行了改变,例如自增的(++)操作,使得指针没有指向内存块的首地址,也会出现这种错误。一般地,在申请到内存后需要指针运算的,拷贝一份指针变量进行运算,而原指针变量则保持不变。


        我遇到的问题是属于第二类的第一种,但是涉及到了多线程的问题,比较隐蔽。具体是这样的:

        有四个队列A1,A2,B1,B2,有两个线程需要通过一个类D的函数将A1,A2中的数据取出来,并复制一份,放入B1,B2。我在类D中定义了一个成 员变量M用于临时存放A1,A2中的数据。当第一个线程将A1中数据赋给M之后,还没有将M放入B1之前,可能第二个线程就把M又赋成了A2中的数据。这 样最后存放入B1,B2就是同一份数据,也就是两个指针指向了同一块内存。这样,在释放内存的时候,就会出现delete两次同一块内存的情况了。

        这种情况下,给成员变量M加锁,或者使用两个成员变量分别对应两个线程,都可以解决这个问题。

            欢迎转载,转载请注明出处http://guoyb.com/Tech/27.html

0

阅读 评论 收藏 转载 喜欢 打印举报/Report
  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 电话:4000520066 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有