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 ??
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.
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.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With