Вопрос

В моем приложении QT я использую QnetWorkAccessManager в потоке, чтобы сделать мою основную поток свободным для выполнения своей задачи. За каждую операцию получения, которую я делаю, я храню QnetWorkReply* в списке, и после ответа я получаю ее из своего списка, удаляю запись в списке и вызовет DeLetelater () в объекте QnetWorkReply*. Однако после пары запросов/ответов, вот сбой, который я получаю во время выполнения:

Код, который я использовал,:

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 (оператор Delete) в потоке 1 (отсутствующая информация отладки). Sexcection по адресу 0x637837aa, код: 0xc0000005: Читать нарушение доступа к: 0xfffffffcdcdcdc1, flags = 0x0

Стек вызовов:

0 Оператор DELETE MSVCR90D 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 :: Handlenotifications QnetWorkReplyImpl.cpp 358 0x6406c99d
6 QnetWorkReplyImpl :: Event 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_internal_proc QeventDispatcher_win.cpp 506 0x67206bf9
13 isThreadDesktopComposited user32 0x77bb86ef
14 isthreaddesktopcomposited user32 0x77bb8876
15 isthreaddesktopcomposited user32 0x77bb89b5
16 DispatchMessagew user32 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 0x636edff3
24 beginThreadex msvcr90d 0x636edf89
25 BASHETHREADINITTHUNK KERNEL32 0 0x77191194
26 rtlinitializexceptionchain ntdll 0 0x77ccb429
27 rtlinitializexceptionchain ntdll 0 0x77ccb3fc

Я использую MSVC для составления кода QT. Любой головы в том, в чем может быть проблема?

Спасибо,

Вишну.

Это было полезно?

Решение

Не рассматривая свой фактический код и на основе описания ошибки, возможно, что вы удаляете QnetWorkReply, прежде чем он испускает finished сигнал Таким образом, после удаления, когда становятся доступными новые данные - QnetWorkReply издает readyRead Сигнал, который будет, когда он будет пытаться получить доступ к уже удаленной записи, и, следовательно, ошибки «нарушение доступа к чтению».

Другие советы

Просто идея:

Поскольку вы используете DeletElater (), вы не знаете, когда будет выполняться удаление, и, таким образом, когда указатель QnetWorkReply* может быть недействительным в вашем списке.

Таким образом, может быть, попробуйте завернуть указатель в указатель Гуарса (Qpointer) и затем просто удалите его из списка, если он удалил/нулевой. Если это все еще действительный указатель, вы называете DeLetelater ();

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top