【问题标题】: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)); ^

标签: c++ c opencv


【解决方案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 我认为这很明显,请参阅答案中的编辑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-21
  • 1970-01-01
  • 1970-01-01
  • 2018-04-19
相关资源
最近更新 更多