最近在做一個機械手視覺系統標定的項目,映像方面用的是OpenCV,近些天老是偶爾出現記憶體方面的問題,很疑惑,發現原因後感慨自己實在是太菜了。
由於待處理的映像都是灰階映像,對於一般IplImage*結構的初始化是這樣的:
IplImage* pImage=cvCreateImage(size,depth,channel);
釋放是這樣的:
cvReleaseImage(&pImage);
我為了方便,自訂了函數:
void CreateImage(IplImage* pImage,int nWidth,int nHeight)
{
pImage=cvCreateImage(cvSize(nWidth,nHeight),IPL_DEPTH_8U,1);
}
void ReleaseImage(IplImage*pImage)
{
cvReleaseImage(&pImage);
}
我這樣調用:
IplImage*m_pImage=NULL;
CreateImage(m_pImage,500,500);
結果發現初始化無效,仔細一想,原來cvCreateImage的實質是先分配記憶體,再返回這片記憶體的指標,那麼對於上述兩句,在函數內部,開始時pImage=m_pImage,調用了cvCreateImage後,pImage這個臨時指標變數指向了新開闢的記憶體,而此時m_pImage仍然指向空,也就是初始化時的NULL,導致初始化無效。
同樣的,如果事先為m_pImage分配了記憶體,釋放時調用函數如下:
ReleaseImage(m_pImage);
結果發現,m_pImage本身沒有被釋放,但是它的成員imageData的內容發生改變,事實上它的資料已經被釋放,本身又沒有置成NULL,如果有其他指標指向了這部分記憶體塊,由於我們在使用m_pImage之前,往往會通過if語句判斷其是否為NULL來確定其狀態,如果發現它不是NULL,就有可能對這塊記憶體進行誤操作,造成意想不到的結果。
所以使用指標要額外小心,自訂形參為指標的函數時也需要特別注意。