Memory Leak issue due to dynamic creation of a QNetworkAccessManager object, locally inside a member function.
-
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.
-
Can you do something like:
qnam->deleteLater();
?
-
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.
-
.@ 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 ?
-
but qnam is created on the heap, on his example
-
... 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. ;)
-
However, maybe I just got the description wrong.
I suggest a pool of QNetworkAccessManager objects. -
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. -
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.
@
-
What is the exact error given by QXmlStreamReader ?