c++qtqnetworkaccessmanagerqnetworkreplyqnetworkrequest

QNetworkReply throwing SIGSEGV when finished signal emitted


My application makes use of QNetworkReply's for send and receiving data from a RESTful API.

There are many tutorials available for using the QNetworkReply with QNetworkAccessManager

Once such example which I used can be found here or even here

Basic Usage:

// Header

QNetworkAccessManager *manager;
QNetworkReply *myReply;
QMetaObject::Connection conReply;

// Making the request

void MainWindow::makeRequest(QString url) {
    //...
    QNetworkRequest request(QUrl(url));
    myReply = manager->get(request) // or post(request)
    conReply = QObject::connect(myReply, SIGNAL(finished()), this,  SLOT(myReplyResponse()));
}

// Handling the request

void MainWindow::myReplyResponse(){
    QObject::disconnect(conReply);

    QByteArray data = myReply->readAll();
    // or QByteArray data = myReply->read(myReply->bytesAvailable());

    myReply->deleteLater();

    // do something with this data

    //...
}

Using a similar implementation, I request data every X seconds.

Problem:

When receiving the finished() signal, the code handling the reply is triggered, but when reading the data, I get a SIGSEGV.

This issue seems to occur at random, thus I cannot determine what triggers it.

Any suggestions would be gladly accepted.


Solution

  • What is probably happening is that it is delaying the order, let's say that an order is sent every second but it takes 2 seconds to replicate, after 2 seconds you have read the reply and you have deleted it from memory, when the other comes myReply is an empty pointer. What you must do is use sender() to obtain the replica, and it is always advisable to validate that you do not have an empty pointer:

    *.h

    private:
        QNetworkAccessManager *manager;
    

    *.cpp

    [...]
    manager = new QNetworkAccessManager(this);
    [...]
    void MainWindow::makeRequest(const QString &url)
    {
        Qurl mUrl(url);
        QNetworkRequest request(mUrl);
        QNetworkReply *myReply = manager->get(request); // or post(request)
        connect(myReply, &QNetworkReply::finished, this,  &MainWindow::myReplyResponse);
    }
    
    void MainWindow::myReplyResponse()
    {
        QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
        if(reply){
            QByteArray data = reply->readAll();
            qDebug()<<data;
            reply->deleteLater();
        }
    }