中止答复因访问冲突而崩溃

问题描述 投票:3回答:1

我有一个大问题,我确实以为自己解决了。我有一个使用QNetworkAccessManager的应用程序。此QNAM位于类中。当我在此QNAM上执行请求时,所有请求都在包装器中完成,该包装器保留答复并对其进行重试逻辑]

例如,如果我在构造函数中有一个putBlob(继承自baseRequest),则将引用传递给QNAM。我拒绝执行请求并保存指向回复的指针。这样,答复将是包装子,因此QNAM不再拥有该所有权。包装器是保存QNAM的原始类的子级。

类具有一个QNAM,子级为“ putBlobRequest”,其子级为“ QNetworkReply *”]

现在的问题是,当用户想要取消时,应该删除主对象及其中的所有内容。包装程序还应该中止其QNetworkReply并断开连接(以便它不调用finish())

我在baseRequest上的析构函数(它拥有QNetworkReply并且是其父代)看起来像这样:

if(_reply) {
    if(_reply->isRunning()) {
        _reply->disconnect(SIGNAL(finished()));
        _reply->disconnect(SIGNAL(uploadProgress(qint64, qint64)));
        _reply->abort();
    }
}

当包装器在保存它的类中被杀死时完成删除。(对吗?]

这有时可行,但是有时我遇到严重的访问冲突,并且以下调用堆栈会导致所有崩溃:

QtCored4.dll!QObject::disconnect(const QObject * sender, const char * signal, const QObject * receiver, const char * method)  Line 2891 + 0x8 bytes C++
QtNetworkd4.dll!QNetworkReplyImpl::abort()  Line 874 + 0x18 bytes   C++
FrameworkAzure.dll!BaseRequest::~BaseRequest()  Line 129 + 0xa bytes    C++
FrameworkAzure.dll!PutBlobRequest::~PutBlobRequest()  Line 24 + 0x5e bytes  C++
FrameworkAzure.dll!PutBlobRequest::`scalar deleting destructor'()  + 0xb bytes  C++
FrameworkAzure.dll!AzureBlobStorageProvider::~AzureBlobStorageProvider()  Line 41 + 0xa8 bytes  C++

因此首先调用abort(),它调用以下代码:

if (d->outgoingData)
    disconnect(d->outgoingData, 0, this, 0); <--- we go in here

将我带到QOBject.cpp中的2891行:

const QMetaObject *smeta = sender->metaObject(); 

由于错误而崩溃:

[CloudSync.exe中0x66c2c490(QtCored4.dll)的未处理异常:0xC0000005:访问冲突读取位置0xdddddddd。

地址“ 0xdddddddd”是“发送者”。

为什么发件人对象不可读?我究竟做错了什么?请帮助!

编辑:

也尝试过:

if(_reply) {
    if(_reply->isRunning()) {
        disconnect(_reply, SIGNAL(finished()), this, SLOT(handleFinishedRequest()));
        _reply->abort();

    }
}

在这里我也断开了派生的putBlob中的uploadProgress。也尝试了不断开连接但存在违反“发送方”的问题

c++ qt access-violation qnetworkaccessmanager
1个回答
0
投票

就我而言,我具有如下的replyFinished功能:

void MyClass::replyFinished(QNetworkReply *reply)
{
   ...
   delete reply;
}

在我的程序中,此函数是通过QNetworkAccessManager连接的,因此即使我调用了断开连接(reply,...),回复也不会断开。命令abort将触发此功能(replyFinished)并删除答复,我又删除了一次(通过reply-> deleteLater()),导致崩溃。

解决方案:添加属性以进行答复和检查。

disconnect(reply, nullptr, this, nullptr);
reply->setProperty("deleting", 1);
reply->abort();
...
void MyClass::replyFinished(QNetworkReply *reply)
{
   if (reply->property("deleting").isValid())
      return;

   ...
   delete reply;
}
© www.soinside.com 2019 - 2024. All rights reserved.