2016-05-17 2 views
0

Я продолжаю получать нарушение сегментации во втором вызове QGraphicsScene :: addItem().QT 5.6: Нарушение сегментации во втором вызове 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 - единственный предмет в сцене. Сцена не активна.

Я перестроил QT с вариантами отладки для Windows MSVC 2015, и вы можете увидеть множество деталей, но запутывания шаблонов 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))); // <<<<<<<<< 
+0

Вам действительно нужно уничтожить объект QApplication и воссоздать его? Большинство программ Qt содержат один объект QApplication в течение всего процесса (например, объявленный как объект стека в верхней части main() или аналогичный); Я подозреваю, что уничтожение и повторное создание объекта QApplication - это то, что разработчики Qt не ожидали, поэтому может быть ошибка, о которой они не знают. –

+0

Хм, наша инфраструктура приложения удаляет QApplication при завершении. Я попытался пропустить это удаление и все еще получил SIGSEGV в QCoreApplication :: postEvent(); – Lee

ответ

0

Там нет необходимости 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); 

код даже может быть короче, но он начнет быть менее читаемым.

+0

AFAICT «вы уничтожаете ppm, пока он все еще используется» не соответствует действительности. Я что-то упускаю? –

+0

Нет, вы этого не сделали, эта фраза должна была быть удалена после того, как я понял, что неправильно читаю образец кода. QPixmap является неявным разделяемым классом, удаление его в этом порядке в порядке, так как оно должно только уменьшать счетчик ссылок. – SGaist

Смежные вопросы