c++qtqnetworkaccessmanagerqnetworkreply

QNetworkAccessManager memory issues


I am developing an application that sends requests to a server using QtNetworkAccessManager and stores the replies. I've made it work but the memory usage is increasing continuosly until and it block the whole PC. I think the problem is related with calling deletelater() and the event loop, but I can't see how to fix it. Here is the code:

main.cpp

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    ReadConfig();
    Ethernet M2;
    return a.exec();
}

Ethernet.h

class Ethernet : public QObject
{
    Q_OBJECT

public:
    Ethernet();
    ~Ethernet();
    QTimer *timer;

private
    QNetworkAccessManager *manager;

public slots:
    void Cycle();
    void replyAuthenticationRequired(QNetworkReply *reply, QAuthenticator *auth);
    void replyFinished(QNetworkReply *reply);
};

Ethernet.cpp

Ethernet::Ethernet() 
{
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(Cycle()));
    timer->start(1000);

    manager = new QNetworkAccessManager(this);
    connect(manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(replyAuthenticationRequired(QNetworkReply*,QAuthenticator*)));
    connect(manager, SIGNAL(finished(QNetworkReply*)), this,     SLOT(replyFinished(QNetworkReply*)));
}

void Ethernet::Cycle()
{
    for (BYTE i=0; i< NUM_TOTAL_VEHICLES; i++)
    {
        FailCheck(i,FILTER_VALUE_PRIORITY_A1);
        FailCheck(i,FILTER_VALUE_PRIORITY_A);
        FailCheck(i,FILTER_VALUE_PRIORITY_B);
        FailCheck(i,FILTER_VALUE_PRIORITY_C);
    }
}

void Ethernet::FailCheck (BYTE coach, BYTE priority)
{
    //Build a valid URL
    QString qsURL = "http://";
    ...
    ..
    .
    //

    manager->get(QNetworkRequest(QUrl(qsURL)));
}

void Ethernet::replyAuthenticationRequired(QNetworkReply *reply, QAuthenticator *auth)
{
   if(!reply->error())
   {
       auth->setUser(DB_USR);
       auth->setPassword(DB_PWD);
   }
   reply->deleteLater();
}

void Ethernet::replyFinished (QNetworkReply *reply)
{
    if(!reply->error())
    {
        //Do some task with the reply;
    }
    reply->deleteLater();
}

I will appreciate any suggestions. Thank you!


Solution

  • If your class is not a thread then it should not inherit QThread. Inherit it from QObject or, if you can't, start your M2 thread. Right now your thread loop for the Ethernet doesn't work and it seems like the network replies have an affinity to your Ethernet event loop(the requests to delete them are posted to the Ethernet event loop, which is not started).

    Or rather, your slots are never executed at all, so the network replies get created but they will never have a chance to be deleted since your slots never executed(because of the said reason) so if I'm not mistaken the network replies live in the main thread so deleteLater should correctly delete them but it is never called.