2013-04-08 2 views
4

Я хотел бы подтвердить, что метод cv::Mat::release() аналогичен методу free() в программировании на С, т. Е. Его освобождает данные матрицы от памяти.cv :: Метод выпуска Mat

В частности, я хотел бы понять поведение этого метода в отношении утечек памяти и убедиться, что утечки в программах can отсутствуют.

+0

инкапсулировать код внутри какое-то время (правда) {// Цикл} и дайте ему поработать. В то же время, контролируйте свою память с помощью диспетчера задач, чтобы рассуждать о вашей памяти. – William

+0

Существуют специальные инструменты для измерения утечек памяти и других ошибок программирования (с использованием неинициализированных переменных и т. Д.). Взгляните на «valgrind». –

ответ

6

Если контрольный счетчик равен единице, то да, cv::Mat::release() будет декрементировать его до нуля и освободить структуру (например, free в C).

Если счетчик ссылок больше единицы (то есть. Есть некоторый другой объект заинтересован в структуре), то cv::Mat::release() будет только декремент счетчик ссылок.

Вы можете увеличить опорный счетчик структуры cv::Mat (то есть, чтобы отметить, что вы заинтересованы в нем, и вы не хотите, чтобы он был освобожден) путем вызова метода cv::Mat::addref().

+0

У меня есть cv :: Mat v, и это v.create() внутри цикла, а размер v различен для разных итераций. то для следующей итерации мне нравится удалить старый для создания нового. Могу ли я использовать release() или deallocate()? – Bryanyan

4

Вам не нужно вручную освобождать cv :: Mat объекты, поскольку он автоматически управляется, если вы не инициализировали Mat из Iplimage, в этом случае вы должны вручную освободить его освободить().

Обратитесь к этой теме.

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

+2

является 'refcount' публичным полем? Я не могу найти его общедоступным ... – zhangxaochen

0

Следующая программа сниппет проверяет поведение Мат :: Release() (адаптировано из 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

Смежные вопросы