博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++中Delete时堆错误(Heap Corruption)的原因
阅读量:3659 次
发布时间:2019-05-21

本文共 965 字,大约阅读时间需要 3 分钟。

最近这三四天一直在跟一个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加锁,或者使用两个成员变量分别对应两个线程,都可以解决这个问题。

            欢迎转载,转载请注明出处

你可能感兴趣的文章
Codeforces Round #638 (Div. 2) D. Phoenix and Science(数学+思维)
查看>>
Codeforces Round #576 (Div. 1) C. Matching vs Independent Set(思维好题)
查看>>
Codeforces Round #639 (Div. 2) D. Monopole Magnets(bfs+模拟)(恶心的阅读理解题)
查看>>
一分钟搞懂与、或、非、异或优先级!
查看>>
CodeBlocks无法编译的解决方案
查看>>
关于ZigBee的学习笔记1.0
查看>>
秒懂!用通俗的话讲解“ZigBee终端节点入网”过程
查看>>
完美解决:Ubuntu 12.04右键没有打开终端选项
查看>>
快速理解:memmove和memcopy的区别
查看>>
strsep函数详解
查看>>
秒懂之atoi()函数!
查看>>
一分钟快速理解:模拟信号和数字信号!
查看>>
MQTT之QoS
查看>>
【JavaWeb开发】"web应用程序的根目录"与"web站点的根目录"的分析
查看>>
【JavaWeb开发】EL表达式和JSTL标签的使用
查看>>
Spring学习(6)-Spring Bean的生命周期
查看>>
Spring学习(8)-AOP之ProxyFactoryBean、RegexMethodPointcutAdvisor、BeanNameAutoProxyCreator
查看>>
Spring学习(9)-AOP之使用aop:config标签
查看>>
【JavaWeb】常见数据库和JDBC错误的解决思路
查看>>
springmvc的静态资源无法访问解决方法(基本全面)
查看>>