双指针指向同一内存的释放问题
2015-06-29 21:45
316 查看
1,问题
写代码的时候遇到一个问题,在方法类里面有个成员变量IplImage* resultImageToDisp,在主函数里面有个局部变量IplImage* resultImage,我需要将resultImageToDisp赋值给resultImage,但只是浅拷贝,就是说resultImageToDisp和resultImag两个图像指针指向了同一内存,主函数结束时按惯例使用cvReleaseImage(&resultImage),但是在退出函数体时候调用方法类的析构函数,此析构函数也存在一个cvReleaseImage(&resultImageToDisp),这样就造成同一内存释放两次报错。本来简单以为在析构时添加一个if(resutlImageToDisp!=NULL)判断语句就可以解决问题,可是还是报错。那么问题来了,NULL的作用是什么,此处添加什么判断语句可以解决问题?
2,抽象
该问题抽象成以上一段代码,即寻找if判断语句。
3,思路
首先,我想到的是判断指针是否为NULL。由于没能真正理解NULL的作用,想当然认为判断指针是否为NULL,就是判断该指针指向的内存是否为0,这是错误的理解。经过测试,我对同一指针加上NULL判断可以通过,如以下代码。
第一次if成立,第二次不成立,代码完全没问题。而对于双指针指向同一内存却报错,说明,NULL只是判断指针本身,而不是它的内存。
查阅资料才明白,释放内存,如free(),deleate(),只是做了一件事情:斩断指针变量与这块内存的关系。(我觉得应该是将这块内存交还给系统,不再供程序使用)free函数就是把这块内存和指针之间的所有关系斩断。从此指针和那块内存之间再无瓜葛。至于指针变量本身保存的地址并没有改变,但是它对这个地址处的那块内存却已经没有所有权了。那块被释放的内存里面保存的值也没有改变,只是再也没有办法使用了。更斩草除根的办法是释放后马上悬空地址,即将指针置为NULL:将指针保存的地址清除,使其不指向任何内存。
这样可以解释,opencv的cvReleaseImage函数,一定包括释放内存和指针悬空两个过程。释放掉resultImage后,该指针指向的内存已经不存在,但是并不影响resultImageToDisp,它任然是一个非NULL的指针,所以if判断语句会失败,而且它的指向内存已经不存在,所以再次释放会报错。
最后,再次查阅资料,发现没有什么好的方法可以处理,囧。。。
4,收获
养成好的习惯,指针变量创建时初始化,要么将指针设置为NULL,要么让它指向合法的内存。
指针指向的内存被释放后,紧接着将指针置为NULL。
别用两个指针指向同一内存这种邪恶的东西。
参考:
http://bbs.csdn.net/topics/80162678
http://www.cnblogs.com/haore147/p/3647437.html
写代码的时候遇到一个问题,在方法类里面有个成员变量IplImage* resultImageToDisp,在主函数里面有个局部变量IplImage* resultImage,我需要将resultImageToDisp赋值给resultImage,但只是浅拷贝,就是说resultImageToDisp和resultImag两个图像指针指向了同一内存,主函数结束时按惯例使用cvReleaseImage(&resultImage),但是在退出函数体时候调用方法类的析构函数,此析构函数也存在一个cvReleaseImage(&resultImageToDisp),这样就造成同一内存释放两次报错。本来简单以为在析构时添加一个if(resutlImageToDisp!=NULL)判断语句就可以解决问题,可是还是报错。那么问题来了,NULL的作用是什么,此处添加什么判断语句可以解决问题?
2,抽象
char *c1,*c2; c1=new char[10]; c2=c1; delete c1; if(/* c2指向的内存空间没有被释放 */) { delete c2; }
该问题抽象成以上一段代码,即寻找if判断语句。
3,思路
首先,我想到的是判断指针是否为NULL。由于没能真正理解NULL的作用,想当然认为判断指针是否为NULL,就是判断该指针指向的内存是否为0,这是错误的理解。经过测试,我对同一指针加上NULL判断可以通过,如以下代码。
if (ROIImageUnsmoothed!=NULL) { cvReleaseImage(&ROIImageUnsmoothed); } if (ROIImageUnsmoothed!=NULL) { cvReleaseImage(&ROIImageUnsmoothed); }
resultImage=resultImageToDisp; cvReleaseImage(&resultImage); if (resultImageToDisp!=NULL) { cvReleaseImage(&resultImageToDisp); }
第一次if成立,第二次不成立,代码完全没问题。而对于双指针指向同一内存却报错,说明,NULL只是判断指针本身,而不是它的内存。
查阅资料才明白,释放内存,如free(),deleate(),只是做了一件事情:斩断指针变量与这块内存的关系。(我觉得应该是将这块内存交还给系统,不再供程序使用)free函数就是把这块内存和指针之间的所有关系斩断。从此指针和那块内存之间再无瓜葛。至于指针变量本身保存的地址并没有改变,但是它对这个地址处的那块内存却已经没有所有权了。那块被释放的内存里面保存的值也没有改变,只是再也没有办法使用了。更斩草除根的办法是释放后马上悬空地址,即将指针置为NULL:将指针保存的地址清除,使其不指向任何内存。
这样可以解释,opencv的cvReleaseImage函数,一定包括释放内存和指针悬空两个过程。释放掉resultImage后,该指针指向的内存已经不存在,但是并不影响resultImageToDisp,它任然是一个非NULL的指针,所以if判断语句会失败,而且它的指向内存已经不存在,所以再次释放会报错。
最后,再次查阅资料,发现没有什么好的方法可以处理,囧。。。
4,收获
养成好的习惯,指针变量创建时初始化,要么将指针设置为NULL,要么让它指向合法的内存。
指针指向的内存被释放后,紧接着将指针置为NULL。
别用两个指针指向同一内存这种邪恶的东西。
参考:
http://bbs.csdn.net/topics/80162678
http://www.cnblogs.com/haore147/p/3647437.html
相关文章推荐
- call Kernelized Correlation Filters Tracker(Matab) in Qt(c++)
- 6月英语
- 我写的一个 Qt 显示图片的控件
- Notification(通知栏)
- 我写的一个 Qt 显示图片的控件
- 网络图片查看器 ——图片可放大缩小
- 重采样内插方法
- halcon二维测量
- 程序员如何解决问题
- nodejs socket error Error:read ECONNRESET
- linux内核之关于内存屏障
- spring 源码解读与设计详解:8 Spring配置文件的读取与容器装配详析
- 测试互联网web网站经验
- 悟道:成功之路在何方
- 质量管理体系建设(图)
- 如何从零开始学习Java语言
- MyEclipse2015+Tomcat+MAVEN+SVN项目环境搭建
- 质量管理:测试基础架构图
- Maven pom.xml配置详解
- 最小二乘法