How to completely free memory of cv::Mat in C++
Asked Answered
A

2

6

when I try to create a cv::Mat and release it afterwards (code below), I still have (according to valgrind) a memory leak by about 1 Byte per Pixel.

Does anyone know how to free the memory of an cv::Mat properly?

Thanks for ansers :)

Code:

int main(int argc, char** argv)
{
  cv::Mat* matrx = new cv::Mat(1000,1000,CV_8UC1,0.);
  matrx->release();
  delete matrx;
  return 0;
}

Valgrind:

[...]
==29420==    1,000,028 bytes in 1 blocks are definitely lost in loss record 372 of 372
==29420==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==29420==    by 0x5438877: cv::fastMalloc(unsigned long) (in /usr/lib/x86_64-linux-gnu/libopencv_core.so.2.4.8)
==29420==    by 0x536FE2A: cv::Mat::create(int, int const*, int) (in /usr/lib/x86_64-linux-gnu/libopencv_core.so.2.4.8)
==29420==    by 0x426FB5: cv::Mat::create(int, int, int) (mat.inl.hpp:663)
==29420==    by 0x426ECD: cv::Mat::Mat(int, int, int, cv::Scalar_<double> const&) (mat.inl.hpp:347)
==29420==    by 0x425A09: main (main.cpp:18)
==29420== 
==29420== LEAK SUMMARY:
==29420==    definitely lost: 1,000,028 bytes in 1 blocks
==29420==    indirectly lost: 0 bytes in 0 blocks
==29420==      possibly lost: 5,072 bytes in 95 blocks
==29420==    still reachable: 304,758 bytes in 1,348 blocks
==29420==         suppressed: 0 bytes in 0 blocks
[...]
Abbott answered 5/9, 2016 at 14:20 Comment(9)
It's usually a bad idea to use pointers to Mat objects because of internal reference counting. Just put them on the stack: int main(){Mat a(10,10,CV_8UC1); return 0;}Gossamer
@Gossamer I just reduced my code to make the question easier and find the issue. I need the Matrix in different classes so need a pointer. Even std::shared_ptr<cv::Mat> didn't solved the problemAbbott
So have one class own it as a non-pointer, and give the rest of the classes a pointer/reference.Tansy
According to the documentation cv::Mat dtor calls release so I think your call to release is redundant, what happens if you only call delete on the pointer?Sphenoid
@Sphenoid same problem even without release()Abbott
I just ran this program with OpenCV 2.4.12 and got no issue with valgrind. The release call is somewhat redundant. Can you post more information (e.g., on how you compiled and linked the above, what headers you included) in case this is a problem with the particular build of OpenCV?Hoyle
@RobertPrévost I actually use OpenCV 3.1.0-dev. the only include is #include <opencv/highgui.h>Abbott
After downgrading to OpenCV 2.4.8 the problem was gone. I reported an issue on GitHub. github.com/opencv/opencv/issues/7238Abbott
I suggested 2.4.8 because the trace in the valgrind output lists a SO from 2.4.8. This might be the root cause. You compiled for 3.1, but the runtime that was used was 2.4.8.Hoyle
J
4

The feedback from opencv github seems clear: you compiled with OpenCV 3.x but use OpenCV 2.4.8 at runtime. Since they are not binary compatible, it does not free properly the cv::Mat. Let export your LD_LIBRARY_PATH to the OCV_DIST/lib of OpenCV 3.x used to compile.

Note that if you delete the pointer you don't even need to release() before.

Jarlath answered 23/9, 2016 at 9:45 Comment(0)
J
1

Quoted the following from the documentation page: (http://docs.opencv.org/2.4.9/modules/core/doc/basic_structures.html#mat-release):

void Mat::release() The method decrements the reference counter associated with the matrix data. When the reference counter reaches 0, the matrix data is deallocated and the data and the reference counter pointers are set to NULL’s.

The above means that when you do "delete matrx;" you are trying to delete a memory zone that already points to NULL, which generates a run-time error.

Juniejunieta answered 18/11, 2016 at 2:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.