Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Memory Leak issue due to dynamic creation of a QNetworkAccessManager object, locally inside a member function.
Forum Updated to NodeBB v4.3 + New Features

Memory Leak issue due to dynamic creation of a QNetworkAccessManager object, locally inside a member function.

Scheduled Pinned Locked Moved General and Desktop
14 Posts 4 Posters 3.6k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • SGaistS Offline
    SGaistS Offline
    SGaist
    Lifetime Qt Champion
    wrote on last edited by
    #2

    Hi and welcome to devnet,

    Why are you creating a new QNAM each time you want to send a request ? You can create it once and use it multiple times, it would be cleaner.

    Interested in AI ? www.idiap.ch
    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

    1 Reply Last reply
    0
    • J Offline
      J Offline
      jeevan_reddy
      wrote on last edited by
      #3

      Hi Gaist,

      Thanks for ur reply. You mean to say I create a member variable and use it.
      If I create a member variable, then I need to call delete each time, before allocating dynamic memory again in a new request.
      The only place where I can delete the QNAM is when I get a reply from the server and finish processing the response, in my case in slot handleServerResponse(). Am I thinking on the correct lines? or the other way is hold to hold each QNAM in a QList and delete the whole container when application is destroyed.

      Thanks,
      Jeevan

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #4

        No, I meant to say: create only one QNAM and keep it.

        You didn't answer my question: why are you creating a QNAM for each request ? QNAM can handle several requests without any problem

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • J Offline
          J Offline
          jeevan_reddy
          wrote on last edited by
          #5

          I tried using a single QNAM to handle multiple requests but the Application always logs an error. My applications always throws up an error in the slot function dealing with processing QNetworkReply for the second request.

          Infact the QXmlStreamReader indicates an error when processing the network reply of second request.

          @QByteArray contents=reply->readAll();
          QXmlStreamReader reader(contents);
          if (reader.hasError())
          {
          qDebug() << "reader returned error";
          }@

          In my case QNam is successfull while dealing with single request but while sending multiple requests, it is failing miserably.

          The XMLReader is always indicating that the reply content has some error.

          1 Reply Last reply
          0
          • I Offline
            I Offline
            igorland
            wrote on last edited by
            #6

            Can you do something like:

            qnam->deleteLater();

            ?

            1 Reply Last reply
            0
            • V Offline
              V Offline
              vidar
              wrote on last edited by
              #7

              You wrote: "In the above code object qnam is created dynamically, since the object created locally gets destroyed when the request method returns".

              I don't think that this is the case.

              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #8

                .@ vidar, it is, an object created on the stack will be destroyed once it's out of scope.

                .@ jeevan_reddy Can you show the complete code of sendRequestToServer and handleServerResponse ?

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                0
                • V Offline
                  V Offline
                  vidar
                  wrote on last edited by
                  #9

                  but qnam is created on the heap, on his example

                  1 Reply Last reply
                  0
                  • V Offline
                    V Offline
                    vidar
                    wrote on last edited by
                    #10

                    ... I mean, that's the reason for the memory leap. ;) Or let's say, the object that qnam points to is still alive after the method is left. So I don't really see a reason for why the signal emit should fail. The only reason could be a badly written connect function. ;)

                    1 Reply Last reply
                    0
                    • V Offline
                      V Offline
                      vidar
                      wrote on last edited by
                      #11

                      However, maybe I just got the description wrong.
                      I suggest a pool of QNetworkAccessManager objects.

                      1 Reply Last reply
                      0
                      • J Offline
                        J Offline
                        jeevan_reddy
                        wrote on last edited by
                        #12

                        vldar: I really think you haven't got the problem I am facing here.

                        the issus is that If I create QNetworkAccessManager object dynamically, I have a memory leak to deal with.
                        If i create the object locally on the stack then I risk the failure of signal/slot mechanism, since the qnam object gets deleted once the method returns.

                        1 Reply Last reply
                        0
                        • J Offline
                          J Offline
                          jeevan_reddy
                          wrote on last edited by
                          #13

                          SGaist : Please find the sample code below uses only one QNetworkAccessManager object to handle multiple requests

                          @
                          MyClientApplication::MyClientApplication()
                          {
                          qnam = new QNetworkAccessManager() ;
                          }
                          void MyClientApplication::sendRequestConfigurationDetails()
                          {
                          /* Create a one-time execute timer to check connectivity with server */
                          download_started_flag = false;

                          /* Form the URL String */
                          QString myurl ="http://" + this->usr->server_address+":"+HTTP_PORT + "/serverrequest/cms.cgi?ACTION=getConfigDetails";
                          
                              QObject::connect(qnam, SIGNAL(finished(QNetworkReply*)),this,
                                                      SLOT(handleServerResponse(QNetworkReply*)));
                          QUrl url = myurl;
                          this->timeoutTimer->start();
                          reply = qnam->get(QNetworkRequest(url));
                          connect(reply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(downloadStatus(qint64)));
                          return;
                          

                          }

                          void MyClientApplication::handleServerResponse(QNetworkReply* reply)
                          {
                          MMCommonError *com_class = new MMCommonError();
                          if ( this->timeoutTimer && this->timeoutTimer->isActive())
                          {
                          this->timeoutTimer->stop();
                          }
                          // error received?
                          if (reply->error() != QNetworkReply::NoError)
                          {
                          com_class->ShowError(HTTP_COMMUNICATION_ERROR);
                          reply->deleteLater();
                          this->setCursor(Qt::ArrowCursor);
                          return;
                          }

                          QByteArray contents=reply->readAll();
                          QXmlStreamReader reader(contents);
                          QString err;
                          int errcode=0;
                          while (!reader.atEnd())
                          {
                          reader.readNext();
                          if (reader.isStartElement())
                          {
                          if (reader.name() == "status")
                          {
                          /* It may be OK or error code */
                          err = reader.readElementText();
                          if (err.compare("OK") == 0) {
                          errcode = 0;
                          } else {
                          errcode = err.toInt();
                          break;
                          }
                          continue;
                          }

                                if (reader.name() == "ServerAddress")
                                {
                           /*do smethg */
                          

                          continue;
                          }
                          if(reader.name() == "CustomerID")
                          {
                          /*do smethg */
                          continue;
                          }
                          if(reader.name() == "Country")
                          {
                          QString country = reader.readElementText();
                          if (!country.isEmpty())
                          {
                          ui->countryComboBox->setEnabled(true);
                          ui->countryComboBox->clear();
                          ui->countryComboBox->insertItem(0,country);
                          this->currentCountry = country;
                          }
                          continue;
                          }
                          if(reader.name() == "City")
                          {
                          QString city = reader.readElementText();
                          if (!city.isEmpty())
                          {
                          ui->cityComboBox->setEnabled(true);
                          ui->cityComboBox->clear();
                          ui->cityComboBox->insertItem(0,city);
                          this->currentCity = city;
                          }
                          continue;
                          }
                          if(reader.name() == "Location")
                          {
                          QString location = reader.readElementText();
                          if (!location.isEmpty())
                          {
                          ui->locationComboBox->setEnabled(true);
                          ui->locationComboBox->clear();
                          ui->locationComboBox->insertItem(0,location);
                          this->currentLocation = location;
                          }
                          Continue;
                          }

                              }
                          

                          } /*xml reader has reached its end, end of while loop */

                                  if(isStatusConnected)
                                  {
                                         sendRequestCountryList();
                                  } 
                                        if (reader.hasError()) {
                                      qDebug() << "reader returned error";
                                      errcode = HTTP_COMMUNICATION_ERROR;
                            }
                            if (errcode != 0) {
                                      com_class->ShowError(errcode);
                                      reply->deleteLater();
                                      this->setCursor(Qt::ArrowCursor);
                                      return;
                            }
                            this->setCursor(Qt::ArrowCursor);
                            reply->deleteLater();
                            return;
                          

                          }

                          Note: the method sendRequestCountryList() creates another request and sends it to client. Basically we are sending second request from the method which handles the first request from server.

                          @

                          1 Reply Last reply
                          0
                          • SGaistS Offline
                            SGaistS Offline
                            SGaist
                            Lifetime Qt Champion
                            wrote on last edited by
                            #14

                            What is the exact error given by QXmlStreamReader ?

                            Interested in AI ? www.idiap.ch
                            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                            1 Reply Last reply
                            0

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved