我什么时候可以删除提供给QImage的数据?

时间:2017-04-25 21:02:21

标签: multithreading qt delete-operator qimage

我像这样创建QImage

unsigned char* const rawImage = (unsigned char*)std::malloc(WIDTH*HEIGHT*3);
for ( ... ) {
    // Populate the image here
}
QImage img(rawImage, WIDTH, HEIGHT, QImage::Format_RGB888);

然后我将该图像的信号发布到另一个线程(特别是GUI线程):

emit imageRendered(img);

我以为我之后可以删除数据:

delete rawImage;

但是这会导致另一个线程中出现分段错误。如果我不删除原始图像,程序将消耗所有可用内存。如何制作QImage的安全副本以便我可以删除我的原始数据?

1 个答案:

答案 0 :(得分:0)

文档非常具体:

  

缓冲区必须在QImage的整个生命周期内保持有效   未经修改或以其他方式分离的副本   原始缓冲区。图像不会在销毁时删除缓冲区。   您可以提供一个函数指针 cleanupFunction 以及一个额外的   最后一个副本时将调用的指针 cleanupInfo   破坏。

您使用以下构造函数:

QImage::QImage(uchar *data, int width, int height, Format format, QImageCleanupFunction cleanupFunction = Q_NULLPTR, void *cleanupInfo = Q_NULLPTR)

您可以安全地使用实际的清理指针。

至于制作数据的实际副本,请记住QImage使用CoW,调用非const函数可能会起作用(虽然我自己没有测试过):

uchar *QImage::bits()
  

请注意,QImage使用隐式数据共享。此功能执行   共享像素数据的深拷贝,从而确保了这个QImage   唯一使用当前返回值的人。

您也可以尝试auto newImage = img.copy();