Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory corruption error while using auto_ptr

Tags:

c++

opencv

I have written a sample code to learn working of auto_ptr, but when I am running my sample code I am getting memory corruption.

My sample code is given below..

#include <iostream>
#include <memory>
#include <cv.h>
#include <highgui.h>
using namespace std;
int main()
{
  for (int i = 0; i < 1000; i++)
  {
    IplImage* temp = cvLoadImage("sample.png");
    auto_ptr<IplImage> aptr (temp);
  }
}

Following is the error message that I got from the above program:

*** glibc detected *** ./a.out: double free or corruption (out): 0x00000000008325c0 ***
======= Backtrace: =========
/lib64/libc.so.6[0x36eb276166]
/lib64/libc.so.6[0x36eb278ca3]
./a.out[0x400e9b]
./a.out[0x400df7]
/lib64/libc.so.6(__libc_start_main+0xfd)[0x36eb21ed1d]
./a.out[0x400cf9]
======= Memory map: ========
00400000-00402000 r-xp 00000000 00:19 7879127                            

Can anybody tell the reason for the above error ??

like image 808
Deepak Avatar asked Jan 26 '26 17:01

Deepak


2 Answers

IplImage* allocated through cvLoadImage() must be released with cvReleaseImage().

cvLoadImage() uses malloc() and cvReleaseImage() uses free() to do the job, while auto_ptr uses delete (which is from C++).

You just can't mix malloc() with delete.

like image 94
karlphillip Avatar answered Jan 28 '26 08:01

karlphillip


After looking at the comments on karlphillip's answer, I'm going to update this answer to use, cvReleaseImage.

It should be pointed out that you can accomplish this with unique_ptr because it will let you specify a custom deleter:

unique_ptr<IplImage, void(*)(IplImage*)> aptr(cvLoadImage("sample.png"), [](IplImage* temp){cvReleaseImage(&temp);});

This will allow you to use an auto-pointer without changing cvLoadImage and still delete the memory correctly.

EDIT:

unique_ptr is an owning auto-pointer, meaning that it will execute it's deleter to cleanup the allocated memory that it owns: https://en.cppreference.com/w/cpp/memory/unique_ptr

Unlike auto_ptr which always called delete, you can pass a custom deleter to unique_ptr.

When passing a custom deleter in the unique_ptr you need to provide the functor signature to the unique_ptr.

So to break my code down:

  • unique_ptr<IplImage, void(*)(IplImage*)> : This is a unique_ptr which will contain an IplImage*. The deleter returns void and takes an IplImage* as an argument.
  • aptr(cvLoadImage("sample.png"), : This is argument needs to be a manageable pointer which the unique_ptr will take ownership of, or a nullptr. Obviously cvLoadImage is returning the manageable pointer.
  • [](IplImage* temp){cvReleaseImage(&temp);}); : This the custom deleter that I'm passing to unique_ptr. I'm wrapping it in a lambda so I can dereference the managed pointer held by unique_ptr cause according to this cvReleaseImage needs to take a pointer to the reference to be deleted.
like image 40
Jonathan Mee Avatar answered Jan 28 '26 08:01

Jonathan Mee



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!