如何在指向Mat析构函数的指针上调用delete~Mat()

时间:2014-04-11 15:18:50

标签: c++ opencv

我有这个函数来删除一个指向A Mat的指针,我建议你更新它来调用Mat析构函数以方便删除:

    void cv_x_Mat(void* ptr) {
        delete (Mat*)ptr;
    }

这似乎没有编译,但没有发布错误,因为我认为任何人都能看到熟悉Destructors的错误。任何帮助表示赞赏。

    void cv_x_Mat(void* ptr) {
        Mat::~Mat() {delete ptr;};
    }

2 个答案:

答案 0 :(得分:3)

您可以使用Mat :: release()释放矩阵内存:

cv::Mat *ptr = new cv::Mat(1000, 1000, CV_8UC3);
ptr->setTo(cv::Scalar(255, 0, 0));
// some code
ptr->release(); // DON'T release manually ptr->data
delete ptr;     // this will call delete[] on ptr->data

你甚至可以省略release(),因为cv :: Mat析构函数会为你做这件事:

cv::Mat *ptr = new cv::Mat(1000, 1000, CV_8UC3);
ptr->setTo(cv::Scalar(255, 0, 0));
// some code
delete ptr;     // this will call delete[] on ptr->data

Mat :: release是删除安全的。如果做了两次,不会造成任何不良副作用。

答案 1 :(得分:1)

无法发表评论,因为我缺乏代表,但我是user3517736引用的同事。我们正致力于将OpenCV绑定到其他语言,因此我们正在解决跨语言边界的内存管理难题。

我建议他做的正是marol所建议的。我假设(现已确认)该释放将由析构函数调用,所以他需要做的是传递一个extern“C”函数,它调用Mat指针上的delete,如下所示:

extern "C" void cv_delete_Mat(Mat* self) {
    delete self;
}

并将该对象的终结器作为目标语言的垃圾收集器传递给适当的C interop(user3517736中的Common Lisp)。

在Haskell(我的目标)中,这意味着将指针视为ForeignPtr,并使用调用cv_Mat_delete的终结器显式构造它。如果有人好奇,我可以扩展这个。

我认为出现了混乱,因为我试图解释一个使用C语言和GC的语言可能会尝试在指针上调用free,这对于通过new初始化的对象是不正确的。问题进一步复杂化,终结器可能被调用为对free的调用 - 这显然是有问题的,在这种情况下正确的答案是显式调用析构函数,或者只是Mat :: release()。前者显然也推广到其他OpenCV类型。

所以这里是最常用的解决方案,应该适用于大多数FFI,并且很容易推广到其他类型:

extern "C" void cv_delete_Mat(Mat* self) {
    self->~Mat();
}

当然,对免费的(隐式)调用仍然是错误的,但是如果不尝试将FFI本身扩展到包含C ++,那么就没有什么可以做的 - 在这种情况下,所有这一切都没有实际意义。< / p>

希望能够回答OP的问题以及本页的后续内容。