QT 5.6:对QGraphicsScene::addItem()的第二次调用中出现分段冲突
QT 5.6: Segmentation violation in second call to QGraphicsScene::addItem()
在对QGraphicsScene::addItem()的第二次调用中,我一直遇到分段冲突。
以下代码第一次工作,但在终止/重新加载QDialog、QApplication等(在DLL中调用)后,代码在第二次使用相同的映像时始终失败!?!
这让我怀疑析构函数是否干净地终止了,或者我是否需要以不同的方式重新初始化QApplication。
有什么建议吗?这是我有问题的代码。。。
PBITMAPINFOHEADER pDIBInfoHeader = (PBITMAPINFOHEADER)m_pImage;
QGraphicsScene *pgs = new QGraphicsScene();
pgs->setSceneRect(0.0, 0.0, 70.0, 80.0);
QSize qs(70, 80);
int width = pDIBInfoHeader->biWidth;
int height = pDIBInfoHeader->biHeight;
uchar *pBits = (uchar *)m_pImage + sizeof(BITMAPINFOHEADER);
QImage *pqi = new QImage((uchar *)pBits, width, height, QImage::Format_Grayscale8);
QImage qiFlip = pqi->mirrored(false, true); //flip image vertically
delete pqi;
QPixmap *ppm = new QPixmap;
if (!ppm->convertFromImage(qiFlip.scaled(qs, Qt::KeepAspectRatio), Qt::NoFormatConversion))
cdbg << "ppm->convertFromImage false" << endl;
// DOES QGRAPHICSPIXMAPITEM TAKE OWNERSHIP OF QPIXMAP?
QGraphicsPixmapItem *item = new QGraphicsPixmapItem(*ppm, 0);
delete ppm;
pgs->addItem(item); // <<< SIGSEGV
ui->grXray->setScene(pgs);
注意:pgs是场景中唯一的项目。场景未处于活动状态。
我用Windows MSVC 2015的调试选项重建了QT,可以看到很多细节,但C++模板、QVariant和QMetaType的复杂性让我无法理解。我应该在哪里查找损坏?
以下是SIGSEGV:的调用堆栈
QMetaType::construct(void * where, const void * copy) Line 2153 C++
`anonymous namespace'::customConstruct(QVariant::Private * d, const void * copy) Line 1020 C++
QVariant::QVariant(const QVariant & p) Line 1372 C++
QGraphicsItem::itemChange(QGraphicsItem::GraphicsI temChange change, const QVariant & value) Line 7447 C++
QGraphicsScene::addItem(QGraphicsItem * item) Line 2496 C++
QT代码片段:
inline void *QMetaType::construct(void *where, const void *copy) const
{
if (Q_UNLIKELY(isExtended(ConstructEx)))
return constructExtended(where, copy);
return m_constructor(where, copy); //<<<<<<<<
}
QVariant::QVariant(const QVariant &p)
: d(p.d)
{
if (d.is_shared) {
d.data.shared->ref.ref();
} else if (p.d.type > Char) {
handlerManager[d.type]->construct(&d, p.constData()); //<<<<<<
d.is_null = p.d.is_null;
}
}
void QGraphicsScene::addItem(QGraphicsItem *item)
...
// Notify the item that its scene is changing, and allow the item to
// react.
const QVariant newSceneVariant(item->itemChange(QGraphicsItem::ItemSceneChange,
QVariant::fromValue<QGraphicsScene *>(this))); // <<<<<<<<<
不需要在堆上构造pqi
和ppm
当ppm还在使用时,你也在破坏它
更干净的代码版本是:
QImage image((uchar *)pBits, width, height, QImage::Format_Grayscale8);
QImage flippedImage = image.mirrored(false, true); //flip image vertically
QPixmap pixmap = QPixmap::fromImage(flippedImage.scaled(qs, Qt::KeepAspectRatio));
pgs->addPixmap(pixmap);
代码甚至可以缩短,但可读性会开始降低。
相关文章:
- getopt_long_only第二次调用时返回 -1
- 读取文件在第二次调用时返回INVALID_HANDLE
- 当再次触发信号时,从Qt插槽执行的功能被第二次调用时会发生什么?
- 第二次调用 PyObject_CallObject() 失败
- 第二次调用 PyObject_CallObject() 时分段错误
- rsa_private_decrypt第二次被调用时会崩溃
- CIN.IGNORE删除第一个字符的第二次函数被调用
- 在具有相同种子的同一程序中对srand()的第二次调用不会为连续的rand()生成相同的值
- QT 5.6:对QGraphicsScene::addItem()的第二次调用中出现分段冲突
- 为什么在第二次调用时使用默认参数时此模板专用化失败
- 在循环中第二次调用luaT_pushudata时失败
- 如果我对async_read进行两次调用,那么只有在处理完第一次调用之后,才会处理第二次调用,这是否安全
- 第二次调用共享对象时崩溃
- CIN 将字符串的开头分配给 int,仅在第二次调用中失败
- 在第二次调用中生成不同的随机数
- 从第二次调用开始在函数中执行一段代码
- Memcpy 始终复制该值,即使不第二次调用它
- GLUT警告:第二次调用glutInit
- c++:几乎相同的输入,但第二次调用显示段故障
- 对于在同一地址构造两次的对象,编译器如何知道必须调用第二个析构函数