Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Memory leak on Mat creation

Valgrind is telling me the following:

==8885== 458,704 bytes in 1 blocks are definitely lost in loss record 17,981 of 18,027
==8885==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8885==    by 0x33C0BA90: cv::fastMalloc(unsigned long) (in /usr/local/lib/libopencv_core.so.2.4.5)
==8885==    by 0x33C51BF1: cv::Mat::create(int, int const*, int) (in /usr/local/lib/libopencv_core.so.2.4.5)
==8885==    by 0x4196CD: cv::Mat::Mat(int, int, int, cv::Scalar_<double> const&) (mat.hpp:353)
==8885==    by 0x41BEA6: clustering::mergeImages(cv::Mat, cv::Mat, std::string, std::string, float, float) (clustering.cpp:128)
==8885==    by 0x41C582: clustering::mergePerceps(percepUnit, percepUnit, std::string) (clustering.cpp:205)
==8885==    by 0x41D6E5: clustering::cluster(std::list<percepUnit, std::allocator<percepUnit> >&, std::list<percepUnit, std::allocator<percepUnit> >&, std::string) (clustering.cpp:428)
==8885==    by 0x41FA45: segmentationClusteringThread::tick() (segmentationClusteringThread.cpp:351)
==8885==    by 0x41FF41: segmentationClusteringThread::threadedFunction() (segmentationClusteringThread.cpp:425)
==8885==    by 0x501AD2: ofThread::run() (in /home/bbogart/Projects/svn/Dreaming-Machine-3/trunk/DM/bin/DM)
==8885==    by 0x578E52: Poco::ThreadImpl::runnableEntry(void*) (in /home/bbogart/Projects/svn/Dreaming-Machine-3/trunk/DM/bin/DM)
==8885==    by 0x34E6BE99: start_thread (pthread_create.c:308)

Following is the mergeImages function:

Mat clustering::mergeImages(Mat scratch, Mat unit, const string maskOrImage, const string FGBG, const float scratchWeight, const float unitWeight) {

    int width, height, type;
    Mat merged, scratchImagePad, unitImagePad, scratchImage, unitImage;
    Mat *smallImage, *bigImage;

    // use the resolution and aspect of the largest of the pair.
    if (unit.cols > scratch.cols)
        width = unit.cols;
    else
        width = scratch.cols;

    if (unit.rows > scratch.rows)
        height = unit.rows;
    else
        height = scratch.rows;

    if (maskOrImage == "mask") 
        type = CV_8UC1; // single channel mask
    else if (maskOrImage == "image")
        type = CV_8UC3; // three channel image
    else
        cout << "maskOrImage is not 'mask' or 'image'\n";

    merged = Mat(height, width, type, Scalar::all(0));
    scratchImagePad = Mat(height, width, type, Scalar::all(0));
    unitImagePad = Mat(height, width, type, Scalar::all(0));

    // weight images before summation.
    scratchImage *= scratchWeight;
    unitImage *= unitWeight;

    // copy images into padded images.
    scratch.copyTo(scratchImagePad(Rect((scratchImagePad.cols-scratchImage.cols)/2,
                                             (scratchImagePad.rows-scratchImage.rows)/2,
                                              scratchImage.cols,
                                              scratchImage.rows)));


    unit.copyTo(unitImagePad(Rect((unitImagePad.cols-unitImage.cols)/2,
                                       (unitImagePad.rows-unitImage.rows)/2,
                                        unitImage.cols,
                                        unitImage.rows)));

    merged = scratchImagePad+unitImagePad;

    // blur mask on background objects
    if (maskOrImage == "mask" and FGBG == "BG") {
        gpu::GpuMat gInputImage, gOutputImage;
        gInputImage.upload(merged);
        gpu::blur(gInputImage, gOutputImage, Size(5,5)); // WAS Size(height*.15,width*.15); // blur with kernel to blow up to full size.
        gOutputImage.download(merged);

        gInputImage.release();
        gOutputImage.release();
    }

    return(merged);
}

I've already posted a general question about memory leaks at Mats here (http://answers.opencv.org/question/14798/what-is-the-best-practise-for-passing-cvmats/), but I wanted to concentrate on this specific code, since its the greatest "definite" leak according to valgrind.

Thank you.