fmvpsenior
fmvpsenior

Reputation: 197

Memory leak c++/cli method

It looks like this method is creating a memory leak when called. If I don't call it, there's no memory leak. Any idea what's causing it?

The function is part of a c++/cli dll that is being called by a c# app.

List<array<Byte>^>^ writejpeg( cv::Mat ovrImagePrevious, List<array<Byte>^>^ overviewOneImages, Dictionary<String^,List<array< Byte >^>^>^ violationAssets, String ^ value, int fileCorruptFlag ) 
{
    vector<uchar> buf1;//buffer for coding
    vector<int> param = vector<int>(2);
    param[0]=CV_IMWRITE_JPEG_QUALITY;
    param[1]=100;//default(95) 0-100
    int img_sz1=ovrImagePrevious.cols*ovrImagePrevious.rows;
    array <Byte>^ hh1 = gcnew array<Byte> (img_sz1);

    if (fileCorruptFlag==1)
    {img_sz1=1;
    hh1=nullptr;}
    else
    {

    cv::imencode(".jpeg", ovrImagePrevious, buf1, param);
    for(int i=0; i <  buf1.size(); i++)
        {
        hh1[i] = buf1[i];
        }

    }

    if(!violationAssets->TryGetValue(value, overviewOneImages))
    {
        overviewOneImages = gcnew List<array<Byte>^>();
        violationAssets->Add(value, overviewOneImages);
    }

    overviewOneImages->Add(hh1);

    return overviewOneImages;


}

UPDATE#1:

When I remove this line:

overviewOneImages->Add(hh1);

the leak goes away.

I need to do this line differently. Any ideas?

UPDATE#2:

It turns out the leak happens when the function is called in that part of the code

    if(!violationAssets->TryGetValue("OVERVIEW_ONE", overviewOneImages))
    {
        cv::Mat f1;
        captureOverview>>ovrImageCurrent; 

        if (fileCorruptFlag==0)
            f1= ovrImageCurrent;

        if (windowOn && !fileCorruptFlag)
        {
            cv::namedWindow( "Frame1", 1 ); 
            cv::imshow( "Frame1", f1 );  
            cv::waitKey(1);
        }

    overviewOneImages = writejpeg(f1, overviewOneImages,   violationAssets,"OVERVIEW_ONE",fileCorruptFlag);


    }

and it looks like it's due the line

       f1= ovrImageCurrent;

Changing it to

       ovrImageCurrent.copyTo(f1) 

fixes it.

Any idea why the first is incorrect and cannot be disposed? Also is there a better way to fix it?

Upvotes: 0

Views: 502

Answers (1)

Jim Mischel
Jim Mischel

Reputation: 133950

Greatly simplified, your code looks like this:

hh1 = allocate a bunch of memory
add hh1 to overviewOneImages
return overviewOneImages

Every time you call that function, assuming that hh1 isn't set to null, you're going to eat a little more memory. After all, your overviewOneImages list maintains a reference to the allocated memory, so the garbage collector can't free it.

In addition, there is code that will allocate a new list in some situations, and that list gets added to the violationAssets dictionary. Again, the dictionary maintains a reference to the allocated memory, so the garbage collector can't release it.

You need to remove things from your list (or dictionary) when you're done using them.

Upvotes: 5

Related Questions