QMap 迭代器崩溃

QMap iterator crash

本文关键字:崩溃 迭代器 QMap      更新时间:2023-10-16

所以我一直在做一个小项目,我想从JPEG中读取EXIF数据,将其存储在地图中,以便稍后在QListView中显示。

所以为了获得exif数据,我有这个

void CImageMeta::cacheEXIF()
{
    if(!isValid()) return;
    if(m_path.isEmpty()) return;
    QString rootPath = CConfig::getInstance()->getMainConfig()->value("root", "./").toString();
    QString fpath = rootPath+m_path;
    //TODO: get EXIF data with libEXIF
    char *buf = 0;
    ExifData *data = exif_data_new_from_file(fpath.toStdString().c_str());
    for(unsigned i = 0; i < data->ifd[EXIF_IFD_EXIF]->count; i++)
    {
        buf = (char*)calloc(256, 1);
        exif_entry_get_value(data->ifd[EXIF_IFD_EXIF]->entries[i], buf, 255);
        //nbuf = ;
        m_cachedEXIF.insert(QString::fromUtf8(exif_tag_get_name(data->ifd[EXIF_IFD_EXIF]->entries[i]->tag)), QString::fromUtf8(buf));
        free(buf);
    }
    for(QMap<QString, QString>::iterator it = m_cachedEXIF.begin(); it != m_cachedEXIF.end(); it++)
    {
        qDebug() << it.key() << " " << it.value();
    }
    exif_data_free(data);
}

这工作正常,最后一个循环是出于调试原因而存在的,并且工作正常,并且整齐地输出所有EXIF数据。

但是,当我想显示它时,我有这个

if(img->cachedEXIF().size() <= 0) return;
ui->tblEXIFData->clearContents();
ui->tblEXIFData->setColumnCount(img->cachedEXIF().size());
for(QMap<QString,QString>::iterator it = img->cachedEXIF().begin();it != img->cachedEXIF().end(); it++)
{
    ui->tblEXIFData->setItem(i,0,new QTableWidgetItem(it.key()));
    ui->tblEXIFData->setItem(i,1,new QTableWidgetItem(it.value()));
    i++;
}

在那里,第一次迭代有效,但第二次迭代已经导致调试器显示 it 值无法访问,并且 thir 迭代最终在 QMap::iterator::next()/it++ 上崩溃。

所以我不知道这里发生了什么。img 指针正确指向对象,映射似乎完好无损(就调试器显示的内容而言)。

编辑:

根据要求回溯:

Thread 3 (Thread 0x7fffde59f700 (LWP 12319)):
#0  0x00007ffff3b7e8bf in pthread_cond_wait@@GLIBC_2.3.2 () from /usr/lib/libpthread.so.0
No symbol table info available.
#1  0x00007ffff3f10a14 in ?? () from /usr/lib/libQt5Script.so.5
No symbol table info available.
#2  0x00007ffff3f10a59 in ?? () from /usr/lib/libQt5Script.so.5
No symbol table info available.
#3  0x00007ffff3b79314 in start_thread () from /usr/lib/libpthread.so.0
No symbol table info available.
#4  0x00007ffff4f773ed in clone () from /usr/lib/libc.so.6
No symbol table info available.
Thread 2 (Thread 0x7fffe91b6700 (LWP 12318)):
#0  0x00007ffff4f7839d in recvmsg () from /usr/lib/libc.so.6
No symbol table info available.
#1  0x00007ffff0e2e917 in ?? () from /usr/lib/libxcb.so.1
No symbol table info available.
#2  0x00007ffff0e2cc61 in ?? () from /usr/lib/libxcb.so.1
No symbol table info available.
#3  0x00007ffff0e2e56f in xcb_wait_for_event () from /usr/lib/libxcb.so.1
No symbol table info available.
#4  0x00007fffeb3a8b49 in ?? () from /usr/lib/qt/plugins/platforms/libqxcb.so
No symbol table info available.
#5  0x00007ffff57f43be in ?? () from /usr/lib/libQt5Core.so.5
No symbol table info available.
#6  0x00007ffff3b79314 in start_thread () from /usr/lib/libpthread.so.0
No symbol table info available.
#7  0x00007ffff4f773ed in clone () from /usr/lib/libc.so.6
No symbol table info available.
Thread 1 (Thread 0x7ffff7fb8780 (LWP 12314)):
#0  0x00007ffff5a220b5 in QVariant::QVariant(QString const&) () from /usr/lib/libQt5Core.so.5
No symbol table info available.
#1  0x00007ffff6b8c8ac in QTableWidgetItem::QTableWidgetItem(QString const&, int) () from /usr/lib/libQt5Widgets.so.5
No symbol table info available.
#2  0x000000000040c60b in MainWindow::displayImageInfo (this=0x7fffffffe5a0, img=0xbc7470) at ../fotomanager/mainwindow.cpp:242
        it = {i = 0xc59690}
        i = 1
        dispImg = 0x4
        dispPM = <incomplete type>
#3  0x000000000040c431 in MainWindow::on_lstImages_itemClicked (this=0x7fffffffe5a0, item=0xbe5c30) at ../fotomanager/mainwindow.cpp:226
        imgID = 2
        img = 0xbc7470
#4  0x0000000000428a34 in MainWindow::qt_static_metacall (_o=0x7fffffffe5a0, _c=QMetaObject::InvokeMetaMethod, _id=4, _a=0x7fffffffd4b0) at moc_mainwindow.cpp:114
        _t = 0x7fffffffe5a0
#5  0x0000000000428bec in MainWindow::qt_metacall (this=0x7fffffffe5a0, _c=QMetaObject::InvokeMetaMethod, _id=4, _a=0x7fffffffd4b0) at moc_mainwindow.cpp:152
No locals.
#6  0x00007ffff5a0f4d4 in QMetaObject::activate(QObject*, int, int, void**) () from /usr/lib/libQt5Core.so.5
No symbol table info available.
#7  0x00007ffff6b802b2 in QListWidget::itemClicked(QListWidgetItem*) () from /usr/lib/libQt5Widgets.so.5
No symbol table info available.
#8  0x00007ffff5a0f40d in QMetaObject::activate(QObject*, int, int, void**) () from /usr/lib/libQt5Core.so.5
No symbol table info available.
#9  0x00007ffff6b1c865 in QAbstractItemView::clicked(QModelIndex const&) () from /usr/lib/libQt5Widgets.so.5
No symbol table info available.
#10 0x00007ffff6b255e3 in QAbstractItemView::mouseReleaseEvent(QMouseEvent*) () from /usr/lib/libQt5Widgets.so.5
No symbol table info available.
#11 0x00007ffff6b49a7e in QListView::mouseReleaseEvent(QMouseEvent*) () from /usr/lib/libQt5Widgets.so.5
No symbol table info available.
#12 0x00007ffff6917fa8 in QWidget::event(QEvent*) () from /usr/lib/libQt5Widgets.so.5
No symbol table info available.
#13 0x00007ffff6a1a5fe in QFrame::event(QEvent*) () from /usr/lib/libQt5Widgets.so.5
No symbol table info available.
#14 0x00007ffff6b2ba0b in QAbstractItemView::viewportEvent(QEvent*) () from /usr/lib/libQt5Widgets.so.5
No symbol table info available.
#15 0x00007ffff59e04fa in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) () from /usr/lib/libQt5Core.so.5
No symbol table info available.
#16 0x00007ffff68d9f2c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/libQt5Widgets.so.5
No symbol table info available.
#17 0x00007ffff68dfbe6 in QApplication::notify(QObject*, QEvent*) () from /usr/lib/libQt5Widgets.so.5
No symbol table info available.
#18 0x00007ffff59e070b in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib/libQt5Core.so.5
No symbol table info available.
#19 0x00007ffff68de0d3 in QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool) () from /usr/lib/libQt5Widgets.so.5
No symbol table info available.
#20 0x00007ffff693685d in ?? () from /usr/lib/libQt5Widgets.so.5
No symbol table info available.
#21 0x00007ffff6938c73 in ?? () from /usr/lib/libQt5Widgets.so.5
No symbol table info available.
#22 0x00007ffff68d9f4c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/libQt5Widgets.so.5
No symbol table info available.
#23 0x00007ffff68df36e in QApplication::notify(QObject*, QEvent*) () from /usr/lib/libQt5Widgets.so.5
No symbol table info available.
#24 0x00007ffff59e070b in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib/libQt5Core.so.5
No symbol table info available.
#25 0x00007ffff5f09636 in QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) () from /usr/lib/libQt5Gui.so.5
No symbol table info available.
#26 0x00007ffff5f0ae75 in QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) () from /usr/lib/libQt5Gui.so.5
No symbol table info available.
#27 0x00007ffff5ef058f in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/libQt5Gui.so.5
No symbol table info available.
#28 0x00007fffeb3ce800 in ?? () from /usr/lib/qt/plugins/platforms/libqxcb.so
No symbol table info available.
#29 0x00007ffff365ca1d in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
No symbol table info available.
#30 0x00007ffff365cd08 in ?? () from /usr/lib/libglib-2.0.so.0
No symbol table info available.
#31 0x00007ffff365cdbc in g_main_context_iteration () from /usr/lib/libglib-2.0.so.0
No symbol table info available.
#32 0x00007ffff5a38137 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/libQt5Core.so.5
No symbol table info available.
#33 0x00007ffff59de132 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/libQt5Core.so.5
No symbol table info available.
#34 0x00007ffff59e5aec in QCoreApplication::exec() () from /usr/lib/libQt5Core.so.5
No symbol table info available.
#35 0x000000000040ab60 in main (argc=1, argv=0x7fffffffe708) at ../fotomanager/main.cpp:10
        a = <incomplete type>
        w = {<QMainWindow> = {<No data fields>}, static staticMetaObject = {d = {superdata = 0x7ffff6fdc480 <QMainWindow::staticMetaObject>, stringdata = 0x71cbc0 <qt_meta_stringdata_MainWindow>, data = 0x71cec0 <qt_meta_data_MainWindow>, static_metacall = 0x4288f8 <MainWindow::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)>, relatedMetaObjects = 0x0, extradata = 0x0}}, ui = 0xaf4990, folderScan = 0xb70e70, ratingWidget = 0xb87bc0, tagWidget = 0xbe1c90, currentAlbum = 0x40aa10 <_start>, currentPicture = 0xbe5c30}

这些情况下的常见错误是cachedEXIF().begin()/cachedEXIF().end()失败,因为cachedEXIF()返回容器的副本 - 两次。而且不能从容器的一个副本迭代到另一个副本。

解决方案:for (auto&& exif: cachedEXIF() )并可能通过引用返回容器。