使用auto_ptr时内存损坏错误

时间:2014-12-19 12:45:42

标签: c++ opencv

我已经编写了一个示例代码来学习auto_ptr的工作,但是当我运行示例代码时,我的内存损坏了。

我的示例代码如下:

#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);
  }
}

以下是我从上述程序中收到的错误消息:

*** 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                            

有人可以说出上述错误的原因吗?

2 个答案:

答案 0 :(得分:5)

通过IplImage* 分配的

cvLoadImage()必须cvReleaseImage()一起发布。

cvLoadImage()使用malloc()cvReleaseImage()使用free()来完成工作,而auto_ptr则使用delete(来自C ++)。

您无法将malloc()delete混合。

答案 1 :(得分:4)

在查看有关karlphillip的答案的评论后,我将更新此答案以使用cvReleaseImage

应该指出,您可以使用unique_ptr完成此操作,因为它可以让您指定自定义删除器:

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

这将允许您使用自动指针而不更改cvLoadImage并仍然正确删除内存。

修改

unique_ptr是一个拥有自动指针,这意味着它将执行它的删除工具来清理它拥有的已分配内存:https://en.cppreference.com/w/cpp/memory/unique_ptr

与总是调用auto_ptr的{​​{1}}不同,您可以将自定义删除工具传递给delete

unique_ptr中传递自定义删除时,您需要向unique_ptr提供仿函数签名。

所以要打破我的代码:

  • unique_ptr:这是unique_ptr<IplImage, void(*)(IplImage*)>,其中包含unique_ptr。删除器返回IplImage*并以void作为参数。
  • IplImage*:这个参数需要是一个可管理的指针,aptr(cvLoadImage("sample.png"),将取得所有权,或unique_ptr。显然nullptr正在返回可管理的指针。
  • cvLoadImage:这是我传递给[](IplImage* temp){cvReleaseImage(&temp);});的自定义删除工具。我将它包装在lambda中,因此我可以取消引用由unique_ptr导致的托管指针,因为this unique_ptr需要指向要删除的引用。< / LI>