Qt-QNetworkReply删除operator-Runtime Crash

时间:2011-05-03 00:45:19

标签: qt network-programming qnetworkaccessmanager

在我的Qt应用程序中,我在一个线程中使用QNetworkAccessManager,以便让我的主线程自由地完成它的任务。对于我所做的每个get操作,我将QNetworkReply *存储在列表中,并在响应时,从列表中检索它,删除列表中的条目并在QNetworkReply *对象上调用deleteLater()。但是,在这里发出几个请求/响应后,我在运行时遇到了崩溃:

我使用的代码是:

void NetworkManager::responseFromServer(QNetworkReply* pReply)
{

  // Retrieve the TileRequestMessage.
  QImage *pImage = imageMapper.value(pReply);
  // Get the bytes from the response.
  QByteArray byteArray = pReply->readAll();
  // Load the QImage with the data.
  bool loaded = pImage->loadFromData(byteArray);

  // Remove the request from book-keeping.
  imageMapper.remove(mapIterator.key());
  pReply->deleteLater();
  return;
}

其中pImage是指向QImage类型对象的指针。 Object是预先创建的,其映射到QNetworkReply *的指针存储在QMap中。

我得到的错误是:

  

在线程1中停止在0x637837aa(操作员删除)(缺少调试信息)。   sException:0x637837aa,代码:0xc0000005:读访问冲突:0xffffffffcdcdcdc1,   标志为0x0 =

调用堆栈是:

  

0运算符删除MSVCR90D 0 0x637837aa
  1 QList :: node_destruct qlist.h 418 0x64071704
  2 QList :: free qlist.h 744 0x6407153b
  3 QList :: ~QList qlist.h 718 0x64070b1f
  4 QQueue :: ~QQueue qqueue.h 58 0x6407076f
  5 QNetworkReplyImplPrivate :: handleNotifications qnetworkreplyimpl.cpp 358 0x6406c99d
  6 QNetworkReplyImpl :: event qnetworkreplyimpl.cpp 868 0x6406e646
  7 QApplicationPrivate :: notify_helper qapplication.cpp 4445 0x6507153e
  8 QApplication :: notify qapplication.cpp 3845 0x6506f1ba
  9 QCoreApplication :: notifyInternal qcoreapplication.cpp 732 0x671c2fb1
  10 QCoreApplication :: sendEvent qcoreapplication.h 215 0x671c8159
  11 QCoreApplicationPrivate :: sendPostedEvents qcoreapplication.cpp 1373 0x671c3f0b
  12 qt_internal_proc qeventdispatcher_win.cpp 506 0x67206bf9
  13 IsThreadDesktopComposited USER32 0 0x77bb86ef
  14 IsThreadDesktopComposited USER32 0 0x77bb8876
  15 IsThreadDesktopComposited USER32 0 0x77bb89b5
  16 DispatchMessageW USER32 0 0x77bb8e9c
  17 QEventDispatcherWin32 :: processEvents qeventdispatcher_win.cpp 807 0x67207b96
  18 QEventLoop :: processEvents qeventloop.cpp 150 0x671c0abe
  19 QEventLoop :: exec qeventloop.cpp 201 0x671c0bf0
  20 QThread :: exec qthread.cpp 490 0x670643d6
  21 DispatcherThread ::运行DispatcherThread.cpp 226 0x1001031a
  22 QThreadPrivate :: start qthread_win.cpp 317 0x6706852f
  23 beginthreadex MSVCR90D 0 0x636edff3
  24 beginthreadex MSVCR90D 0 0x636edf89
  25 BaseThreadInitThunk kernel32 0 0x77191194
  26 RtlInitializeExceptionChain ntdll 0 0x77ccb429
  27 RtlInitializeExceptionChain ntdll 0 0x77ccb3fc

我正在使用msvc来编译我的Qt代码。对问题可能是什么单挑?

谢谢,

2 个答案:

答案 0 :(得分:0)

在不查看实际代码的情况下,根据您的错误说明,您可能会在发出finished信号之前删除QNetworkReply。因此,在删除新数据后,QNetworkReply会发出readyRead信号,该信号将在何时尝试访问已删除的条目,从而导致“读取访问冲突”错误。

答案 1 :(得分:0)

只是一个想法:

由于你使用deleteLater(),你不知道何时会发生删除,因此当你的列表中指针QNetworkReply *可能无效时。

因此,可能尝试将指针包装在一个guared指针(QPointer)中,然后只要将其删除/ null就将其从列表中删除。如果它仍然是一个有效的指针,则调用deleteLater();