一个很难发现的内存泄漏

  当你的资源释放以后,再去访问时,就会出现各种错误,比如对象返回空,资源不存在等等,这些错误都是编译的时候语法合理的,但是一旦运行到了这里,肯定就会出错了(这一块如果没被执行的话,还是发现不了错误的)。而且很难找到这个错误的原因(不在于这个错误有多么的难,而是代码太多,关系太复杂,没有很好地条理去分析,逻辑混乱了以后,就会觉得太可怕了)。因此,找BUG需要时刻保持清醒的头脑,这个BUG我昨天从下午到晚上十点多,一直找都没解出来,今天上午刚起床,来到自习室,冷静的分析了片刻,很快就看出来了问题的症结。

 

设想一下如果申请的堆内存不够我放下想要的数据,但是我确实又把所有想要的数据都放入了其中,会发生什么???

这是一个特别奇葩的内存泄漏,我之前根本就没想过粗心会导致这种错误!!!

当你(new)申请的堆空间只够放下一个对象时(如上图),实际上你却可以用这个指针数组存放不止一个对象,当你存放了2个及以上对象时(也就是超过了申请的堆内存空间),这个时候,编译合法,运行也正常(这点很奇怪,但是这是事实),不过当你的程序退出时,会调用析构函数,如果你在析构函数中手动的释放这块内存的话,就会出现内存泄漏了!!!!!!!!!!

原因:

因为原来只分配了一个对象的内存空间,但是你却向这块内存中放了不止一个对象(这样做 语法正确,运行也正确),因此delete这个指针的时候,只会释放一个内存的空间,因此导致了其余对象的内存空间没有释放,出现了内存泄漏被其他程序检测到(可能是内核又或者是相关的支持程序亦或是程序本身有监测机制),就会提示错误了。

关于new申请内存的个人看法:

如上所述,关于 “申请的堆空间只够放下一个对象时(如上图),实际上你却可以用这个指针数组存放不止一个对象” 为什么能够成功的正常运行。

首先来反推一下,程序能够正常的运行(只是在退出的时候调用一些析构函数释放内存空间出错)说明我实实在在的使用了少量申请到的内存存放了

超过这个内存块大小的数据,并且这些数据是能够被正常访问到的,也就是说这块内存区域对应用程序来说是合法的(否则会报错“内存访问冲突”),

尽管设计者并没有申请这么多的内存。

再联想一下设备的这些硬件资源全部都由内核管理以及分配给应用程序,并且这些由内核管理的内存空间是以最小单位页被分配给应用程序的,所以

申请一个对象的空间的时候,内核会以页为单位分配内存空间给应用程序,所以就会出现  “申请的堆空间只够放下一个对象时(如上图),实际上你却

可以用这个指针数组存放不止一个对象”  的情况了!!!

猜你喜欢

转载自www.cnblogs.com/xwmcc/p/10107626.html
今日推荐