在OpenCv中使用Ptr<IplImage>导致内存异常
Using Ptr<IplImage> in OpenCv causes memory exception
void hello(Mat original)
{
Mat a=original.clone();
Ptr<IplImage> b = &a.operator IplImage();
return;
}
这个函数会导致内存异常。因为我必须使用一个参数为 IplImage* 的旧函数,所以我将 Mat 转换为 Ptr 并导致内存异常。以上功能只是一个简化版。
Ptr<T>
是一个模板 class,它执行包装的 object 指针的自动销毁(有关它的更多信息,请参阅 official documentation)。
在你的代码片段中,a
和 b
都是函数 hello
内部的局部变量,所以它们会在这个函数 returns 和构造顺序相反,所以 a
将在 b
.
销毁后被销毁
可能会出现内存异常,因为两个变量(a
和b
)都引用了相同的内存区域:实际上,函数Mat::operator IplImage
并没有复制 Mat
object 的基础数据 ,但为这些矩阵数据创建 IplImage
header。
因此,当 Mat
析构函数将尝试销毁 object a
时,专用于基础数据的内存部分已经被 b
释放.
The operator creates the IplImage header for the matrix without copying the underlying data. You should make sure than the original matrix is not deallocated while the IplImage header is used.
您可以将返回的 header 的引用传递给接受 IplImage*
的函数,例如下面代码中的 void foo(IplImage* img)
:
#include <opencv2\opencv.hpp>
using namespace cv;
void foo(IplImage* img)
{
// Set to blue
cvSet(img, Scalar(255,0,0));
}
int main()
{
// Small green image
Mat3b img(10, 10, Vec3b(0, 255, 0));
{
// Doesn't modify original image
Mat mat = img.clone();
IplImage ipl = mat;
foo(&ipl);
// ipl and mat are blue now
// img is still green
}
{
// Modify original image
IplImage ipl = img;
foo(&ipl);
// ipl and img are blue now
}
// img is blue
return 0;
}
void hello(Mat original)
{
Mat a=original.clone();
Ptr<IplImage> b = &a.operator IplImage();
return;
}
这个函数会导致内存异常。因为我必须使用一个参数为 IplImage* 的旧函数,所以我将 Mat 转换为 Ptr 并导致内存异常。以上功能只是一个简化版。
Ptr<T>
是一个模板 class,它执行包装的 object 指针的自动销毁(有关它的更多信息,请参阅 official documentation)。
在你的代码片段中,a
和 b
都是函数 hello
内部的局部变量,所以它们会在这个函数 returns 和构造顺序相反,所以 a
将在 b
.
可能会出现内存异常,因为两个变量(a
和b
)都引用了相同的内存区域:实际上,函数Mat::operator IplImage
并没有复制 Mat
object 的基础数据 ,但为这些矩阵数据创建 IplImage
header。
因此,当 Mat
析构函数将尝试销毁 object a
时,专用于基础数据的内存部分已经被 b
释放.
The operator creates the IplImage header for the matrix without copying the underlying data. You should make sure than the original matrix is not deallocated while the IplImage header is used.
您可以将返回的 header 的引用传递给接受 IplImage*
的函数,例如下面代码中的 void foo(IplImage* img)
:
#include <opencv2\opencv.hpp>
using namespace cv;
void foo(IplImage* img)
{
// Set to blue
cvSet(img, Scalar(255,0,0));
}
int main()
{
// Small green image
Mat3b img(10, 10, Vec3b(0, 255, 0));
{
// Doesn't modify original image
Mat mat = img.clone();
IplImage ipl = mat;
foo(&ipl);
// ipl and mat are blue now
// img is still green
}
{
// Modify original image
IplImage ipl = img;
foo(&ipl);
// ipl and img are blue now
}
// img is blue
return 0;
}