使用SetData()分配数据后cvReleaseImage()上的分段错误

时间:2012-01-27 10:53:33

标签: c++ opencv

我正试图从相机中获取单张图像,对它们进行一些处理并释放使用过的内存。我已经用相似的代码执行了很长一段时间了:

char* img_data = new char[ len ]; // I retrieve len from the camera.

// Grab the actual image from the camera: 
// It fills the previous buffer with the image data.
// It gives width and height.

CvSize size;
size.width = width;
size.height = height;
IplImage* img = cvCreateImageHeader( size, 8, 1 );
img->imageData = img_data;

// Do the processing

cvReleaseImage( &img );

此代码运行正常。我最近阅读了here(在imageData描述中),我不应该直接将数据分配给img-> imageData,而是使用SetData(),如下所示:

cvSetData( img, img_data, width );

然而,当我这样做的时候,我在cvReleaseImage()调用时遇到了Segmentation错误。

我做错了什么?

谢谢。

编辑:我已经尝试编译并运行@karlphillip建议的程序,并且我使用cvSetData获得了分段错误,但在直接分配数据时运行正常。 我正在使用Debian 6和OpenCV 2.3.1。

4 个答案:

答案 0 :(得分:2)

我也有这个问题,但相信它是从我收集的内容中解决的 this comment;即使用cvReleaseImageHeader()而不是cvReleaseImage()。

例如:

unsigned int width = 100;
unsigned int height = 100;
unsigned int channels = 1;
unsigned char* imageData = (unsigned char*)malloc(width*height*channels);
// set up the image data

IplImage *img = cvCreateImageHeader(cvSize(width, height), IPL_DEPTH_8U, channels);
cvSetData(img, imageData, width*channels); 

// use img

cvReleaseImageHeader(&img);

// free(imageData) when finished

答案 1 :(得分:1)

问题是你使用C ++方式分配内存(使用new),同时使用OpenCV的C接口,它试图在free()内用cvReleaseImage()释放该内存块。 C和C ++的内存分配不能混合在一起。

解决方案:使用malloc()分配内存:

char* img_data = (char*) malloc(len * sizeof(char)); 
// casting the return of malloc might not be necessary 
// if you are using a C++ compiler

编辑:(由于OP的评论仍在崩溃)

您没有向我们展示的

其他会导致您的应用程序崩溃!我认真地建议您编写一个完整/最小的应用程序来重现您遇到的问题。

以下应用程序在我的Mac OS X中使用OpenCV 2.3.1正常工作。

#include <cv.h>
#include <highgui.h>


int main()
{
    char* img_data = (char*) malloc(625); 

    CvSize size;
    size.width = 25;
    size.height = 25;
    IplImage* img = cvCreateImageHeader( size, 8, 1 );

    //img->imageData = img_data;
    cvSetData( img, img_data, size.width );

    cvReleaseImage( &img );

    return 0;
}

答案 2 :(得分:1)

通常,如果您手动分配标头并设置数据,则应该仅释放 标头并自行释放数据:

// allocate img_data

IplImage* img = cvCreateImageHeader( size, 8, 1 );
img->imageData = img_data;
cvReleaseImageHeader( &img ); // frees only the header

// free img_data

如果您调用cvReleaseImage,它也会尝试释放数据,因此您依赖OpenCV实现来执行此操作,这在您的情况下失败,因为它使用free并且您使用{{1}分配彼此不相容的。 另一种选择是使用new分配并致电malloc

答案 3 :(得分:0)

我想在此讨论中添加一个细节。似乎有某种错误 cvReleaseHeader()函数。 您必须先释放标题,然后释放图像数据。 如果你以另一种方式,即免费图像数据,然后调用cvReleaseHeader()函数,那么欺骗性工作。但在内部它会泄漏内存,一段时间后你的应用程序就会崩溃。