2011-05-03 189 views
0

在我的Qt应用程序中,我在线程中使用QNetworkAccessManager,以便让我的主线程自由地完成任务。对于我所做的每个获取操作,我将QNetworkReply *存储在一个列表中,并在响应时从列表中检索它,删除列表中的条目并调用QNetworkReply *对象上的deleteLater()。然而,一对夫妇在这里请求/响应后坠毁我在运行时得到:Qt- 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(缺少调试信息)。 sException在0x637837aa,代码:0000005:在读访问冲突:0xffffffffcdcdcdc1, 标志=为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 :: handleNotifications 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_internal_proc qeventdi spatcher_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

我使用MSVC编译我的Qt代码。任何抬头问题可能是什么?

谢谢,

Vishnu。

+1

有关如何管理(和删除)QNetworkReply对象的一些代码可能会有所帮助。 – 2011-05-03 05:27:07

+0

修改了问题以添加代码.. – 2011-05-03 19:19:46

回答

0

没有看你的实际代码,并根据你的错误描述,你可能会在发出finished信号之前删除QNetworkReply。因此,在删除新数据后,QNetworkReply会发出readyRead信号,此信号将尝试访问已删除的条目,从而导致“读取访问冲突”错误。

+0

这就是我在槽中调用deleteLater()方法的确切原因。另外,我想知道在QNetworkReply对象被删除后,QNetworkReply如何发出readyRead信号。 – 2011-05-03 18:41:31

+0

此外,在进一步调查中,我发现有时QNetworkReply *的finished()信号在QNetworkAccessManager(其中QNetworkReply *)的finished()信号被删除后触发,因此我的插槽中的发件人连接到finished()信号QNetworkReply *被标记为0x00。如果是这样的话,我应该在哪里删除我的QNetworkReply *对象? – 2011-05-03 19:23:26

+0

对于你的第一个评论,QNetworkReply对象不是由你创建的,它是在'QNetworkAccessManager :: get'中获得的。因此,这意味着您无法控制创建的QNetworkReply对象,因此只要有新数据可供读取,它就会发出'readyRead'信号。 – Purnima 2011-05-04 01:37:04

0

只是一个想法:

由于您使用deleteLater()你不知道什么时候删除会发生,因此当指针QNetworkReply *可以在您的列表中无效。因此,也许尝试将你的指针包装在一个有指针的指针(QPointer)中,然后如果它被删除/ null,就从列表中删除它。如果它仍然是一个有效的指针,则调用deleteLater();