私は OpenCV を使用しており、多数の画像 (Mat
オブジェクト) をベクターに格納したいと考えています。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 は、作成された Mat オブジェクトを参照してメモリ リークの可能性を報告しています。何か不足していますか?
編集:
Ok。どうやら、ポインタを使用したり、を使用して動的に割り当てたりすることは避けたほうがよいようMat
です。代わりに使用するようにコードを変更しました。ただし、 Valgrind レポートで失われた可能性があるために割り当てられたいくつかのブロックがまだ表示されます。また、プログラムの実行中にメモリ使用量が着実に増加していることにも気付きました。Mat
new
std::vector<Mat>
Mat
私が何をしているのかを明確にしましょう。関数で画像を作成し、それらをバッファーに配置しています(内部的にを使用しています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);
}