雙指針指向同一內存的釋放問題


1,問題

  寫代碼的時候遇到一個問題,在方法類里面有個成員變量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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM