删除QNetworkReply*回复导致代码外的SIGSEGV

Delete QNetworkReply *reply cause SIGSEGV outside of the code?

本文关键字:代码 SIGSEGV QNetworkReply 回复 删除      更新时间:2023-10-16

我写了一个简单的程序来自动设置路由器。经过检查,我发现一个指针需要是deletereplyFinish()中的QNetworkReply *reply),并完成了这项工作,但在那之后,程序崩溃和Qt显示它在一些汇编代码中停止了:(

所以我的问题是:

  1. 有什么常见的做法来处理这种情况吗(Qt显示程序在某些汇编代码中停止)

  2. 删除不再使用的指针时,我做错了什么?(很确定)

这是代码:

#ifndef HTTPGETTER_H
#define HTTPGETTER_H
class QNetworkAccessManager;
class QNetworkReply;
class QNetworkRequest;
class QAuthenticator;
#include <QObject>
class httpGetter : public QObject
{
    Q_OBJECT
private:
    QNetworkAccessManager *nam;
public:
    explicit httpGetter(QObject *parent=0);
    ~httpGetter();
public slots:
    void replyFinish(QNetworkReply* reply);
    void onAuthen(QNetworkReply*,QAuthenticator*);
};

实现

#include "httpgetter.h"
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkAccessManager>
#include <QAuthenticator>
#include <QDebug>
httpGetter::httpGetter(QObject *parent) : QObject(parent)
{
    nam = new QNetworkAccessManager(this);
    QObject::connect(nam,SIGNAL(finished(QNetworkReply*)),this,SLOT(replyFinish(QNetworkReply*)));
    QObject::connect(nam,SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)),this,SLOT(onAuthen(QNetworkReply*,QAuthenticator*)));
    QUrl url("http://192.168.1.1");
    QNetworkReply *reply= nam->get(QNetworkRequest(url));

}
httpGetter::~httpGetter(){
    delete nam;
}
void httpGetter::replyFinish(QNetworkReply *reply)
{
    if (reply==NULL) {
        qDebug() << "NULL reply";
        return;
    }
    QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
    qDebug() << statusCode.toString();
    if (reply->error()==QNetworkReply::NoError) {
        qDebug() << "NICE reply";
        QByteArray bytes = reply->readAll();
        QString answer = QString(bytes);
        qDebug()<< answer;
    }
    else {
        qDebug() << "reply error";
    }
    //delete reply; ==> delele cause sigsegv, if don't the program run like a     while(true)
    //reply == NULL;
}
void httpGetter::onAuthen(QNetworkReply* rep,QAuthenticator* auth)
{
    if ( rep==NULL || auth == NULL) {
        qDebug()<< "reply or authentication pointer is null";
        return;
    }
    qDebug()<< rep->readAll();
    auth->setUser("rolan");
    auth->setPassword("123456");
}

#include <QtCore/QCoreApplication>
#include "httpgetter.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    httpGetter abc;


    return a.exec();
}

根据文档:

注意:请求完成后用户可以在适当的时间删除CCD_ 4对象。不要直接在连接到CCD_ 5的插槽内删除。你可以使用deleteLater()函数。

此外,由于

nam = new QNetworkAccessManager(this);

创建一个以this为其父级的新QNetworkAccessManager,而QObject的析构函数将自动删除其所有子级,则httpGetter的析构器中的delete nam;是不必要的,最终将导致双重删除。