每帧动态分配一个 shared_ptr 中的图像

Posted

技术标签:

【中文标题】每帧动态分配一个 shared_ptr 中的图像【英文标题】:Dynamically allocate image in a shared_ptr each frame 【发布时间】:2011-03-05 00:35:44 【问题描述】:

我在这里第一次尝试使用 shared_ptr,但我在执行此操作时遇到了一些麻烦。

我想在每一帧都得到一个 IplImage 并分配给一个 shared_ptr 类成员,释放最后一个图像。是这样的:

class Detector 
public: 
       void Detector::updateImage 
            main_image_.reset(cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 3));
       
private:
       boost::shared_ptr<IplImage> main_image_;

我在循环中调用 updateImage。 cvCreateImage 为该图像大小动态分配一些内存。

循环第一次运行时,一切正常。现在,我第二次收到 _BLOCK_TYPE_IS_VALID 断言错误。当 shared_ptr 试图删除指针时会发生这种情况。

所以,假设我做错了什么,我尝试了许多其他选项,例如:

if (!main_image_) 
    main_image_ = boost::shared_ptr<IplImage> (cvCreateImage...
else
    main_image_.reset(cvCreateImage...)

也没有用。尝试先重置 shared_ptr ,也没有工作。尝试设置一个新的临时 shared_ptr 并分配给我的 main_image_ptr。没有成功。

我哪里错了?使用常规指针并手动释放图像就像一个魅力。

提前致谢,

西奥

【问题讨论】:

IplImagecvCreateImage()的定义是什么? 这与您的shared_ptr 问题无关,但我想指出,为每帧分配 640x480 图像对我来说似乎非常低效。您可能需要考虑重用已分配的图像。查看一种称为“双缓冲”的技术 (en.wikipedia.org/wiki/…)。 @Maxim。 IplImage 是 OpenCV 中使用的一种结构。它保存图像的数据和元数据。 cvCreateImage 也是来自 OpenCV 并为此分配必要的内存。 @Emile:当然你是对的。应该更好地重用相同的图像,只是将所有东西都涂成黑色。甚至不需要使用双缓冲。感谢您的提醒。 【参考方案1】:

我假设您在调试版本中看到此错误?

cvCreateImage() 使用哪种分配内存的方法? new 还是 malloc()boost::shared_ptr 使用 delete 来破坏内存,因此您的系统可能会检测到数据没有以“正确的方式”分配,即使用 new。

如果是这种情况,那么您必须使用带有自定义删除器的 shared_ptr(查看 boost 文档以获取更多信息),以便正确释放内存。

【讨论】:

+1 即使cvCreateImage() 不使用new 进行分配,您也可以将自定义释放器分配给shared_ptr 作为constructor 中的第二个参数。 @Sam,这就是我所说的自定义删除器 - 我认为这就是它在 Boost 文档中的名称...... 是的,我只是想添加一条评论来表示我的支持,而不是编辑您的答案。 @Sam 和@Timo,你们明白了! cvCreateImage 使用 malloc 分配新图像。我要试试自定义删除器!非常感谢! @Theo,很高兴你发现了问题。

以上是关于每帧动态分配一个 shared_ptr 中的图像的主要内容,如果未能解决你的问题,请参考以下文章

C++ shared_ptr 持有动态分配的数组

分配 std::shared_ptr

c++动态内存管理与智能指针

c++11智能指针(一) shared_ptr

每帧分配一个新缓冲区以防止屏幕撕裂

shared_ptr源码分析