Question

In my Qt application, I am using QNetworkAccessManager in a Thread so as to keep my main thread free to do its task. For every get operation that I do, I am storing the QNetworkReply* in a list and upon a response, I retrieve it from my list, delete the entry in the list and call deleteLater() on the QNetworkReply* object. However, after a couple of request/responses here is the crash i get in runtime:

The code that I used is:

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;
}

where pImage is a pointer to a object of type QImage. The Object is created in advance and its pointer mapped to a QNetworkReply* is stored in a QMap.

The error I get is:

Stopped at 0x637837aa (operator delete) in thread 1 (missing debug information). sException at 0x637837aa, code: 0xc0000005: read access violation at: 0xffffffffcdcdcdc1, flags=0x0

The call stack is:

0 operator delete 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::run 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

I am using msvc to compile my Qt code. Any heads-up on what the problem might be ??

Thanks,

Vishnu.

Was it helpful?

Solution

Without looking at your actual code and based on your error description, it could be possible that you are deleting the QNetworkReply before it has emitted the finished signal. So after the deletion when new data becomes available - QNetworkReply emits the readyRead signal which is when it would be trying to access the already deleted entry and hence the "read access violation" errors.

OTHER TIPS

Just an idea:

Since you use deleteLater() you do not know when the delete will take place and thus when the pointer QNetworkReply* may be invalid in your list.

Thus, maybe try wrapping your pointer in a guared pointer (QPointer) and then just remove it from the list if it deleted/null. If it's still a valid pointer you call deleteLater();

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top