LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Memory Leak with imaqLineProfile

Solved!
Go to solution

I am trying to use imaqLineProfile to get profile information. A code fragment looks like this:

                for (j=0; j<11; j++)

                {

                                myLineData = imaqLineProfile(image,imaqMakePoint(myColumn, myRow), imaqMakePoint(myColumn, myRow+y_size));

                                for (i = 0; i < myLineData->dataCount; i++)

                                {

                                                myPixVal = (int)(myLineData->profileData[i]);

                                                *(myPlotData+i) += (int)(myPixVal/2200.);                                                          

                                                if (myMin_y > myPixVal) myMin_y = myPixVal;

                                                if (myMax_y < myPixVal) {myMax_y = myPixVal; myMaxLoc_y = i;}

                                }

                                                                               

                                myColumn++;

                }

                my_size = myLineData->dataCount; 

 

I use the max and mins to help make a graph on the screen. Once the graph has been drawn, I call "imaqDispose(myLineData)" to release the memory. This works fine, except that the memory use grows with each call. If I replace the imaqLineProfile with my own function to populate the array with test data. It works fine, memory size stays constant. I suspect I should be releasing some other bit of memory, but I can't find an example that would illuminate what other variables are allocated by the call. 

 

Does anyone have a sample code that uses imaqLineProfile?

 

Thanks,

Dr. Otter 

 

0 Kudos
Message 1 of 6
(2,691 Views)

According to the documentation, imaqDispose is what you have to call to clear memory associated with imaqLineProfile, so the memory leak may arise elsewhere in the code.

CVI offers the Resource Tracking utility to address this kind of issues: by setting the debugging level to Extended in Build options dialog you will enable this feature. Run your app for a while and after closing it the Resource Tracking Window will appear listing all meory blocks allocated and not freed: double clicking on one of them will jump to the code where the allocation appears, easing up the process of checking memory release operations.

 

(Note: the Resource Tracking is only available in Full edition of CVI)



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 2 of 6
(2,664 Views)

A detailed explanation of Resource Tracking utilities can be found here:

Memory Leak Detection with LabWindows/CVI



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 3 of 6
(2,661 Views)

Thanks for the tip, but I don't see the memory usage changing before or after the function call. I do see the memory usage increasing ~200kb each time an image is grabbed and I see when I release the image. 

 

It seems incredible odd that NI doesn't provide sample code for situations like this. I suspect that there are several variable I need to dispose of including the returned variable. NI Support was un-willing to help out. 

 

I am just going to write my own code and give up on this buggy function. It doesn't look like anyone is using it. 

 

 

0 Kudos
Message 4 of 6
(2,584 Views)
Solution
Accepted by Dr_Otter

I don't see you call imaqDispose() anywhere in that code snippet.

 

The way I understand the documentation, what you should do is something along these lines:

 

for (j = 0; j < 11; j++, myColumn++)
{
    myLineData = imaqLineProfile(image, imaqMakePoint(myColumn, myRow), imaqMakePoint(myColumn, myRow + y_size));
    if (myLineData)
    {
        for (i = 0; i < myLineData->dataCount; i++)
        {
            myPixVal = (int)(myLineData->profileData[i]);
            *(myPlotData+i) += (int)(myPixVal/2200.);                                                          
            if (myMin_y > myPixVal) myMin_y = myPixVal;
            if (myMax_y < myPixVal) {myMax_y = myPixVal; myMaxLoc_y = i;
        }
        imaqDispose(myLineData);
    }
    else
    {
        // memory error
        break;
    }
}

 

Each imaqLineProfile() call allocates a memory block whose pointer it returns. Of course you can't access the interna of that block after you called imaqDispose() so you will need to calculate the my_size inside that loop if you really need it.

 

Basically you calling imaqDispose() only after the loop, you leak 10 (11 - 1)  LineProfile buffers every time you call this code.

 

Reading function documentation is always a little tricky but I think the IMAQ Vision manual is fairly clear about it, although admittingly a bit condensed. Anything else would indicate that imaqLineProfile() is using some static memory internally, and THAT would be a very nasty thing in terms of allowing that function to be used in a multi-threading application!

Rolf Kalbermatter
My Blog
0 Kudos
Message 5 of 6
(2,562 Views)

Got it. That is indeed the issue. Thanks for the clarification.

0 Kudos
Message 6 of 6
(2,548 Views)