1

私の 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 型のオブジェクトへのポインタです。オブジェクトは事前に作成され、QNetworkReply* にマップされたそのポインターは QMap に格納されます。

私が得るエラーは次のとおりです。

スレッド 1 の 0x637837aa (オペレーター削除) で停止しました (デバッグ情報がありません)。sException at 0x637837aa、コード: 0xc0000005: 読み取りアクセス違反: 0xffffffffcdcdcdc1、フラグ = 0x0

コール スタックは次のとおりです。

0 オペレータ削除 MSVCR90D 0 0x637837aa 1 QList:: node_destruct qlist.h
418 0x64071704
2 QList::free qlist.h 744 0x6407153b ::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 0X77194
RTLINITTHRUNK CNEL32 0

msvc を使用して Qt コードをコンパイルしています。問題が何であるかについての注意事項はありますか??

ありがとう、

ヴィシュヌ。

4

2 に答える 2

0

実際のコードを確認せずに、エラーの説明に基づいて、シグナルを送信する前に QNetworkReply を削除している可能性がありますfinished。そのため、新しいデータが利用可能になったときに削除した後、QNetworkReply はreadyRead、既に削除されたエントリにアクセスしようとしているときにシグナルを発し、「読み取りアクセス違反」エラーが発生します。

于 2011-05-03T09:46:22.497 に答える
0

ただのアイデア:

deleteLater() を使用しているため、削除がいつ行われるかがわからないため、リスト内のポインター QNetworkReply* が無効になるタイミングがわかりません。

したがって、ポインターを保護されたポインター ( QPointer ) でラップしてから、削除/null の場合はリストから削除してみてください。それがまだ有効なポインターである場合は、deleteLater(); を呼び出します。

于 2011-05-03T10:39:07.087 に答える