2013-04-08 149 views
4

我想確認在C編程中,cv::Mat::release()方法是否類似於free(),即它從存儲器中取消分配Matrix數據。cv :: Mat的發佈方法

特別是,我想了解這種方法在內存泄漏方面的行爲,並確保可能程序中沒有泄漏。

+0

封裝你的代碼,而內(真){//循環},並讓它運行。與此同時,使用任務管理器監視你的記憶,以推斷你的記憶。 – William 2013-04-08 09:16:26

+0

有特定的工具來衡量內存泄漏和其他編程錯誤(使用未初始化的變量等)。看看«valgrind»。 – 2013-04-08 13:35:14

回答

6

如果參考計數器等於1,那麼是的,cv::Mat::release()會將其遞減至零並釋放結構(如C中的free)。

如果參考計數器大於1(即存在一些對該結構感興趣的其他物體),則cv::Mat::release()將只有遞減參考計數器。

通過調用cv::Mat::addref()方法,您可以遞增cv::Mat結構的引用計數器(即標記您對其感興趣並且不希望它被解除分配)。

+0

我有一個cv :: Mat v,並且這是在一個循環內的v.create(),並且v的大小對於不同的迭代是不同的。然後爲了下一次迭代,我喜歡刪除舊的創建新的。我可以使用release()或deallocate()嗎? – Bryanyan 2013-04-08 13:07:51

4

你不必手動釋放cv :: Mat對象,因爲它是自動管理的,除非你在這種情況下從Iplimage初始化了Mat,所以你應該手動釋放它的deallocate()。

請參閱此主題。

openCV mixing IplImage with cv::Mat

3

我在使用的碼結構是這樣的(OpenCV中與C++)內存泄漏:

int i; 
while(true){ 
    Mat x = imread("C:/pics"+i+".jpg"); 
    //do something with x 
} 

後100次左右的迭代它總是墜毀,然後我改變了代碼以這樣的:

int i; 
while(true){ 
    Mat x = imread("C:/pics"+i+".jpg"); 
    //do something with x 
    x.refcount = 0; 
    x.release(); 
} 

它停止崩潰並做了完整的迭代。但是,當手動將refcount設置爲0時,您必須確定不再需要該對象。這可能是某人投票回答我的答案的原因,但我使用這種方法解決了我的問題。那麼爲什麼我不應該分享它呢?

+0

你能否澄清你的倒票的原因?是否因爲你錯過了我的觀點? – kiltek 2014-04-13 18:33:43

+2

是'refcount'公共領域?我找不到它... – zhangxaochen 2015-07-26 16:17:17

0

下面的程序片斷測試墊的行爲::釋放() (改編自opencv-org-answer

using namespace std; 
using namespace cv; 

int main(int argc, char **argv) { 
    cout << "test_mat_release.cpp" << endl; 

    { 
     //memory is released 
     const char *pzInputImg = "data/em_sample.png"; 

     Mat img; 
     img = imread(pzInputImg); 
     assert(img.data); 
     img.release(); 
     assert(!img.data); 
    } 
    { 
     //memory is released 
     Mat img(100, 100, CV_32FC1); 
     assert(img.data); 
     img.release(); 
     assert(!img.data); 
    } 

    { 
     //Since Mat does not owns data , data is not released 
     //you have to explicitly release data 
     int cols=17; 
     int rows=15; 
     unsigned char * data = new unsigned char[rows*cols*3]; 
     Mat img(rows, cols, CV_8UC3, data); 
     assert(img.data); 
     img.release(); 
     assert(!img.data); 
     delete [] data; 
    } 



    Mat imgRef; 
    { 
     //memory is not released 
     //since there img.data is now shared with imgRef 
     Mat img(100, 100, CV_32FC1); 
     imgRef=img; 
     assert(img.data); 
     assert(img.data == imgRef.data); 
     img.release(); 
     assert(img.empty()); 
     assert(!img.data); 
     //img.data is NULL, but imgRef.data is not NULL, so data is not de-allocated 
     assert(!imgRef.empty()); 
     assert(imgRef.data); 
    } 
    return 0; 
} 
+0

會超級好,如果在最後一個例子中你展示了一種釋放內存的方式,我想通過釋放imgRef然後img ...? – VirgileD 2017-03-20 07:49:33