OpenCV Memory Management

If you’re new to OpenCV, you need to know exactly how to manage all the huge amounts of memory you’re using. C/C++ isn’t a garbage collected language (like Java), so you need to manually release memory as soon as its use is over. If you don’t, your program could use up hundreds of MBs of highly valuable RAM… and often even crash (out-of-memory errors?)

It can be a daunting task to hunt exactly where memory needs to be released. So I’ve compiled this short list of places where you should look out for memory leaks.

Create it, then Release it

If you create something, make sure you release it before “returning”. This is probably the very first thing you should check when fixing memory leak problems with OpenCV. For example, if you do a cvCreateImage, make sure you do a cvReleaseImage. There are many things you can create. Here are some functions that “create” and their corresponding “release” functions

  • cvCreateImage – cvReleaseImage
  • cvCreateImageHeader – cvReleaseImageHeader
  • cvCreateMat – cvReleaseMat
  • cvCreateMatND – cvReleaseMatND
  • cvCreateData – cvReleaseData
  • cvCreateSparseMat – cvReleaseSparseMat
  • cvCreateMemStorage – cvReleaseMemStorage
  • cvCreateGraphScanner – cvReleaseGraphScanner
  • cvOpenFileStorage – cvReleaseFileStorage
  • cvAlloc – cvFree

One warning though: If you create something and want to return it, don’t release it. Lets say a function that creates a checkerboard image and returns it. If you release the image before returning it, you’re freeing all memory that stores the image data. And when you try accessing memory that isn’t yours, you get a crash.

Release returned structures

This is the second thing you should check for. Often, once you return a structure (say, an image).. you forget about it.

Multiple Memory Allocations

This is the third thing you should check for: Allocating memory, and then changing the pointer itself. Here’s some example code:

IplImage* image = cvCreateImage(whatever);
image = CreateCheckerBoard(whatever);
...
cvReleaseImage(&image);

This function creates a memory leak. First, you allocate some memory for image. Then, you call the function CreateCheckerBoard. This function itself creates new memory. And image now points to this new memory. The memory created in the first step is lost forever. No variable points to it. A memory leak. To fix this, you need to modify the code like this:

IplImage* image = NULL;
image = CreateCheckerBoard(whatever);
...
cvReleaseImage(&image);

If you return a sequence, release its storage

There are many instances where you use the CvSeq data structure. And often you might want to return this structure for further use. If you release its storage (a CvMemStorage structure) within the function itself, you’d free the memory where the sequence is stored. And then you’d try and access it in the calling function. Again, crash.

A temporary fix would be to just erasing the cvReleaseMemStorage statement… but that would mean lots of memory.

To fix this, you don’t release the memory in the function itself. You release it in the calling function like this:

cvReleaseMemStorage(&thesequence->storage);

storage is a member of the CvMemStorage structure that always points to the memory where its stored.

Again, this is just an example. There are more structures where a similar situation could arise.

Dependence on other structures

I quite recently discovered this memory leak. To explain this, I’ll use an example: Lets say you find out the contours of an image. OpenCV would return a “linked list” type structure called CvSeq. You decide to access the third element of this linked list. OpenCV returns a pointer to the third element. All going great till this moment.

Now you decide to save all the points of this contour (the third element) in a data structure of your own. Since this is an array of points, you do something like:

mystructure->points = thirdcontour->points;

You set the pointer to equal to the thirdcontour. This is the bug.

If you release the storage of the sequence (which you should), mystructure has a bad pointer. To fix this, allocate new memory to mystructure->points and then copy contents of thirdcontour->points… something like this:

mystructure->points = (CvPoint*)malloc(sizeof(CvPoint) * thirdcontour->total);
memcpy(mystructure->points,thirdcontour->points,sizeof(CvPoint)*thirdcontour->total);

This creates new memory for your structure and then copies each element there. Once you’ve done this, you can release the storage of the sequence without fear :)

Thats it for now

These are the few memory leak problems I’ve encountered till now. Hope this list helped you fix the problem with your program :)

And if you know some more bugs that lead to memory leaks, do let me know… I’ll put it up here!

Issues? Suggestions? Visit the Github issue tracker for AI Shack

Back to top

11 Comments

  1. Posted October 7, 2010 at 7:49 pm | Permalink

    Thanks thats so good.

  2. Kan
    Posted March 9, 2011 at 7:22 am | Permalink

    I call this blog “plagiarism.” You must give credit to http://www.andol.info/hci/963.htm if you are not the same guy.

    • Posted March 9, 2011 at 9:37 am | Permalink

      Hi! I originally wrote this article. You’ll see Andol has put a link back to the original site as well (at the bottom) – http://liquidmetal.in Later on, I moved all OpenCV, etc stuff to AI Shack.

  3. Kan
    Posted March 9, 2011 at 1:21 pm | Permalink

    Please accept my apology. It’s my mistake I did not check it carefully.

  4. Prakriti
    Posted July 6, 2011 at 6:08 pm | Permalink

    Hi!
    I am working in OpenCV and in my code i am accessing 1000 image files of different size and doing lots of processing. i am accessing the image files names from a file and processing one after another. The code is running for each individual image file. But wen i try to run it for all at one go it works till 46 image files and then it behaves in a strange manner for the 47th file and stops. i am not able to debug it. I want ur help. Should I mail you my code… description of the whole thing n send some test data? plz help. its urgent.

    • Posted August 9, 2011 at 6:42 pm | Permalink

      Did you get it to work? I think the problem is you’re not releasing images in the loop. When you’re done using an image, release it. That way, memory can be reused. Use the Processes tab in Task Manager to check the amount of memory it uses.

  5. sabarish
    Posted September 18, 2011 at 4:42 am | Permalink

    Hi ,
    I am a newbie to OpenCv , i would like to know how the memory for the video capturing using a camera are allocated.I came across the structure called CvCapture but there is no specific definition for it.
    could you plese specify some details of how memory is allocated .

    thanks in advance.

  6. Siddharth
    Posted September 22, 2011 at 8:09 am | Permalink

    Nice post!!
    I recently shifted to using the C++ API that opencv provides, and a lot of the memory management headaches automatically went away. Especially if you split your code into smaller C++ objects. Any temporary structures created inside those objects are automatically freed when you delete the object. The code also becomes much cleaner as a result

  7. Posted January 20, 2012 at 3:31 am | Permalink

    I read that if an image is used for capturing from a webcam, you should set the image pointer to 0 before releasing the data, as shown below:

    CvCapture* pCam1 = NULL;
    IplImage* cam1CV = NULL;

    cam1CV = cvQueryFrame(pCam1);

    cam1CV=0; cvReleaseImage(&cam1CV);

    If cam1CV is not set to 0, a runtime error occurs. Are you familiar with this technique, and do you know why it works?

    Thanks!
    Osman

    • Posted January 20, 2012 at 3:37 am | Permalink

      I’ve not heard of this – and you should definitely not set it to 0 before releasing it. In fact, you shouldn’t release it. CvCapture maintains a single image in itself. All images retrieved are stored in this single image (one after the other). When you close the capture device, it automatically releases the image.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>