Qt-QNetworkReply删除运算符-运行时崩溃

Qt-QNetworkReply删除运算符-运行时崩溃,qt,network-programming,qnetworkaccessmanager,Qt,Network Programming,Qnetworkaccessmanager,在我的Qt应用程序中,我在一个线程中使用QNetworkAccessManager,以使我的主线程能够自由地执行它的任务。对于我执行的每个get操作,我都将QNetworkReply*存储在一个列表中,在收到响应后,我从列表中检索它,删除列表中的条目,然后在QNetworkReply*对象上调用delete。但是,经过几次请求/响应之后,我在运行时遇到了崩溃: 我使用的代码是: void NetworkManager::responseFromServer(QNetworkReply* pRep

在我的Qt应用程序中,我在一个线程中使用QNetworkAccessManager,以使我的主线程能够自由地执行它的任务。对于我执行的每个get操作,我都将QNetworkReply*存储在一个列表中,在收到响应后,我从列表中检索它,删除列表中的条目,然后在QNetworkReply*对象上调用delete。但是,经过几次请求/响应之后,我在运行时遇到了崩溃:

我使用的代码是:

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类型对象的指针。该对象是预先创建的,其映射到QNetworkReply*的指针存储在QMap中

我得到的错误是:

在0x637837aa处停止,线程1中的运算符删除缺少调试信息。 0x637837aa处存在异常,代码:0xc0000005:0xFFFFFFCDCDCDCDC1处存在读取访问冲突, 标志=0x0

调用堆栈是:

0操作员删除MSVCR90D 0 0x637837aa 1 QList::node_destruct QList.h 418 0x64071704 2 QList::免费QList.h 744 0x6407153b 3 QList::~QList QList.h 718 0x64070b1f 4 QQueue::~QQueue QQueue.h 58 0x6407076f 5 QNetworkReplyImplPrivate::Handle通知qnetworkreplyimpl.cpp 358 0x6406c99d 6 QNetworkReplyImpl::事件QNetworkReplyImpl.cpp 868 0x6406e646 7 QApplicationPrivate::notify_helper qapplication.cpp 4445 0x6507153e 8 QApplication::通知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_内部程序qeventdispatcher_win.cpp 506 0x67206bf9 13 IsThreadDesktopComposited用户32 0 0x77bb86ef 14 IsThreadDesktopComposited用户32 0 0x77bb8876 15 IsThreadDesktopComposited用户32 0 0x77bb89b5 16 DispatchMessageW用户32 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 qthread private::启动qthread_win.cpp 317 0x6706852f 23 beginthreadex MSVCR90D 0 0x636edff3 24 beginthreadex MSVCR90D 0 0x636edf89 25 BaseThreadInitThunk内核32 0 0x77191194 26 RTL初始化例外链ntdll 0 0x77ccb429 27 RTL初始化例外链ntdll 0 0x77ccb3fc

我正在使用msvc编译我的Qt代码。有人知道问题出在哪里吗

谢谢


毗瑟奴。

在不查看实际代码的情况下,根据您的错误描述,您可能在QNetworkReply发出完成信号之前删除了它。因此,在删除之后,当新数据可用时,QNetworkReply会发出readyRead信号,此时它将尝试访问已删除的条目,因此会出现读取访问冲突错误。

这只是一个想法:

由于使用deleteLater,您不知道何时进行删除,因此指针QNetworkReply*在您的列表中何时无效


因此,可以尝试将指针包装在一个受保护的指针中,如果它已删除/null,则将其从列表中删除。如果它仍然是一个有效的指针,则稍后调用Delete

一些关于如何管理和删除QNetworkReply对象的代码可能会有所帮助。修改问题以添加代码..这正是我在插槽中调用deleteLater方法的原因。此外,我想知道QNetworkReply对象被删除后,QNetworkReply如何发出readyRead信号。此外,进一步调查发现,有时QNetworkReply*的完成信号在QNetworkAccessManager的完成信号被删除后激发,其中QNetworkReply*被删除,因此,连接到QNetworkReply*中已完成信号的插槽中的发送方被标记为0x00。如果是这种情况,我应该在哪里删除我的QNetworkReply*对象???对于您的第一条评论,QNetworkReply对象不是由您创建的,它是在QNetworkAccessManager::get中获得的。因此,这意味着您对由此创建的QNetworkReply对象没有控制权,因此只要有新数据可读取,它就可以发出readyRead信号。请参阅QNetworkAccessManager::finished插槽的文档。明确提到不要在此插槽中删除QNetworkReply对象。因此,您可以尝试在所有网络访问结束时使用deleteLater删除QNetworkReply对象。在对QNetworkReply对象执行deleteLater之前,您可以使用isFinished检查它是否已完成处理。