我使用的是OpenCV,我想將一些圖像(Mat
對象)存儲在一個向量中。我已經聲明矢量如下來存儲指向Mat
對象的指針。在STL容器中存儲OpenCV Mat對象時避免內存泄漏
std::vector<Mat*> images;
的Mat
物體通過使用new
關鍵字創建,然後加入到載體中。
Mat *img = new Mat(height, width, CV_8UC3);
// set the values for the pixels here
images.push_back(img);
我怎麼會去確保我釋放由Mat
對象所佔用的內存以避免內存泄漏?
我在做什麼,現在是這樣的:
Mat *im = images.at(index);
// process and display image here
delete(im);
Valgrind是reporing一個可能的內存泄漏參照創建墊的對象。我錯過了什麼嗎?
編輯:
確定。顯然最好避免使用Mat
指針並使用new
動態分配Mat
。我修改了我的代碼,以代替std::vector<Mat>
。不過,我仍然看到分配的一些區塊可能在Valgrind報告中丟失。我還注意到程序運行時內存使用量穩步增加。
讓我澄清我在做什麼。我在函數中創建圖像並將它們放入緩衝區(內部使用std::deque
)。然後這個緩衝區被另一個函數訪問,以檢索和映像,並將它傳遞給執行處理和渲染的另一個函數。
class Render {
public:
void setImage(Mat& img) {
this->image = img;
}
void render() {
// process image and render here
}
private:
Mat image;
}
線程,不斷地從緩衝區中提取圖像並呈現它們。
void* process(void *opaque) {
ImageProcessor *imgProc = (ImageProcessor*) opaque;
Mat img;
while (imgProc->isRunning) {
// get an image from the buffer
imgProc->buffer->getFront(img);
// set the image
imgProc->renderer->setImage(img);
// process and render
imgProc->renderer->render();
}
}
現在,一切都作爲對象引用傳遞(即Mat&
)。我假設從緩衝區獲取圖像並將其傳遞給渲染函數後,該對象的唯一引用將在該函數中。因此,當我得到另一個圖像時,將不再有對該對象的引用,它將被銷燬。但Valgrind的給了我下面的:
25,952,564 bytes in 11 blocks are possibly lost in loss record 14,852 of 14,853
in ImageProcessor::generateImage() in ImageProcessor.cpp:393
1: malloc in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so
2: cv::fastMalloc(unsigned long) in /usr/local/lib/libopencv_core.so.2.4.2
3: cv::Mat::create(int, int const*, int) in /usr/local/lib/libopencv_core.so.2.4.2
4: cv::Mat::create(int, int, int) in /usr/local/include/opencv2/core/mat.hpp:353
5: cv::Mat::Mat(int, int, int) in /usr/local/include/opencv2/core/mat.hpp:75
...
這裏是generateImage()
:
void generateImage() {
Mat img(h, w, CV_8UC3);
// set values of pixels here
this->buffer->pushBack(img);
}
墊子類管理內存的分配和有引用計數,這樣'的std ::矢量'做的工作適合你,仍然只複製避免不必要的分配和大型矩陣內容的副本的指針加上大小信息。 –
mars
@mars我按照你的建議更新了它的代碼部分後更新了問題。我仍然遇到內存泄漏,但問題仍然存在。 – informer2000
這裏顯示的代碼部分應該可以工作。你能詳細介紹一下這個不透明的指針嗎?它來自哪裏,它如何被初始化,以及誰擁有它,並在不再需要時調用'ImageProcessor'的析構函數?請注意'void * opaque = new ImageProcessor; do_stuff(不透明);自由不透明;'調用'ImageProcessor'的構造函數,但調用'void'的析構函數)。 – mars