我是不是必须在 Opencv C 包装器中为 C++ 接口释放 New 分配的内存
Posted
技术标签:
【中文标题】我是不是必须在 Opencv C 包装器中为 C++ 接口释放 New 分配的内存【英文标题】:Do I have to free memory allocated by New in a Opencv C wrapper for the C++ interface我是否必须在 Opencv C 包装器中为 C++ 接口释放 New 分配的内存 【发布时间】:2014-03-09 19:13:28 【问题描述】:我正在为 C++ OpenCV 函数编写 C 包装器,这是我做的一个
Mat* cv_create_ones(int rows, int cols, int type)
return new Mat(Mat::ones(rows, cols, type));
在大多数包装器中,我首先通过调用 New 来返回。我想知道当我完成它时,我是否必须在我的包装器中使用删除释放由 New 分配的数据......如果是这样,有没有办法将删除合并到上面的包装器中,所以当函数是时自动调用它完成使用......就像每次调用它时它都会创建一个新的,被使用然后调用删除......只有在它再次访问时再次调用新......不,那是行不通的,因为如果我将数据存储在由 new 分配的指针会被删除,对吗?我用谷歌搜索了如何做到这一点,但我没有找到任何东西。专家对此的任何建议表示赞赏。
为 Dima Maligin 编辑
我尝试了以下和 juanchopanza 的变化,但得到了错误
Mat* cv_create_zeros(int rows, int cols, int type)
Mat m(Mat::ones(rows, cols, type)); return &m;;
特别是在这个方面我得到了
警告:返回局部变量“m”的地址
我用谷歌搜索,似乎在这种情况下建议使用 malloc,但随后需要释放它......所以如果您知道解决方法,我将不胜感激。我正在向 github 上的 Arjun Comars Opencv pull 添加新函数,它准备与 main 合并,并且它的添加是为 C++ 代码自动生成 C 包装器,因此没有 c++ ffi 的语言可以包装 opencv c++ 函数。 github https://github.com/arjuncomar/opencv/blob/master/modules/c/src/mat.cpp...I 上的一个示例是希望有人可以查看链接,这是一些包装器,大多数确实使用“新”并且没有它就不会编译,并告诉我是否使用它们我是应该安排稍后释放内存...如果您能猜出他的代码意图并给我建议,我将不胜感激...
【问题讨论】:
确实如此,但您错过了 OpenCV 的 C++ 接口的要点。让cv::Mat
管理自己的资源。不要动态分配它。
@juanchopanza 你能说得更详细点吗......你的意思是我不必打电话给 New......我从一个为 opencv 工作的人那里得到了这段代码,所以我认为它是正确的...... ...我是不是弄错了..是不是错了...请详细说明
是的,不需要new
,也可以查看opencv文档docs.opencv.org/modules/core/doc/…
只需说类似cv::Mat m = cv::Mat::ones(rows, cols, type);
的内容。我真的认为在这里使用new
没有任何优势。
@juanchopanza 我刚刚做了一个快速测试,没有新的上述函数将无法编译,我得到 opencv-glue.cpp:190:43: error: cannot convert 'cv::Mat'以 'cv::Mat*' 作为回报 return Mat(Mat::ones(rows, cols, type)); ^
【参考方案1】:
1- 你不能创建一个局部变量并返回一个引用或指向它的指针
因此:
Mat* cv_create_zeros(int rows, int cols, int type)
Mat m(Mat::ones(rows, cols, type)); return &m;;
是非法的。你返回一个指向已删除对象的指针。
2- 任何new
你都必须delete
。
因此如果调用:
Mat* cv_create_ones(int rows, int cols, int type)
return new Mat(Mat::ones(rows, cols, type));
必须使用delete
删除指针。
因为您编写了一个 c 包装器并且您不能使用 delete
,所以您应该添加一个 delete_mat
函数。
void delete_mat(Mat* m)
delete m;
编辑
由于delete
不仅意味着释放内存,还意味着调用析构函数,您需要为每个需要删除的类型使用delete函数,或者更准确地说,至少对于每个基本类型使用虚拟析构函数。
您不需要为每个使用new
的函数添加删除函数,您只需为每个type。
如果你有 2 个(或更多)函数:
Mat* cv_create_ones(...)
return new Mat(Mat::ones(...));
Mat* cv_create_zeroes(...)
return new Mat(Mat::zeroes(...));
你只需要一个delete
函数来删除一个Mat指针:
void delete_mat(Mat* m)
delete m;
【讨论】:
非常感谢您的回复...我有很多使用 new 的函数,它们是 opencv c++ 的 c 包装器,这是我的文件pastebucket.com/32401 ...这是否意味着我必须为每个函数中的每个对象编写一个删除函数,该函数用删除实例化一个对象......我试图让我的代码不变得笨重......这是唯一的方法...... @EdwardMonney 我认为这很明显,请参阅答案中的编辑。以上是关于我是不是必须在 Opencv C 包装器中为 C++ 接口释放 New 分配的内存的主要内容,如果未能解决你的问题,请参考以下文章
如何创建一个.so 文件,其中仅包含用 C 代码包装的 C++ 代码 - OpenCV 相关?