我想确认cv::Mat::release()
方法是否类似于free()
C 编程中的方法,即它从内存中释放矩阵数据。
特别是,我想了解此方法在内存泄漏方面的行为,并确保在可能的程序中没有泄漏。
如果引用计数器等于 1,那么是的,cv::Mat::release()
会将其减为零并释放结构(如free
在 C 中)。
如果引用计数器大于一(即,有其他对象对结构感兴趣),则只会cv::Mat::release()
递减引用计数器。
您可以通过调用该方法来增加结构的引用计数器cv::Mat
(即,标记您对它感兴趣并且您不希望它被释放) 。cv::Mat::addref()
您不必手动释放 cv::Mat 对象,因为它是自动管理的,除非您已从 Iplimage 初始化 Mat,在这种情况下您应该手动释放它 deallocate()。
请参考这个线程。
我使用这样的代码结构(带有 C++ 的 OpenCV)出现内存泄漏:
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 时,您必须确定您不再需要该对象。这可能是有人对我的答案投反对票的原因,但我使用这种方法解决了我的问题。那我为什么不分享呢?
以下程序片段测试 Mat::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;
}