PDA

View Full Version : Application crash after 2 entries to requestFinished function



mourad
19th October 2011, 11:31
Hello everyone, I've developped an application whitch send a Web service to the server.
For the response, I've user the requestFinished slot. But I've seen that my application enter 2 to this function.
This causes the crash of my application and I've the message shown in the PJ
Can anyone tell me what's wrong ?
Many thanks in advance.
Best regards.

ChrisW67
20th October 2011, 02:25
Most likely you are directly or indirectly using a null or invalid pointer. No code, no further help.

You should be using QNetworkAccessManager instead of QHttp which, as the fine manual says, is:

This class is obsolete. It is provided to keep old source code working. We strongly advise against using it in new code.

mourad
20th October 2011, 08:35
Many Thanks for replying. It's right I've not helped you with more details.
In fact, my application which should connect to the server is
void Connexion::connectToWebService(QString host, quint16 port, QString path, vector <QStringList> paramsList)
{
// formater la chaine à envoyer
QString params;
int i = 0;
int listParamSize = paramsList.size()-1;
while(i <= listParamSize){
if(0 < i){
params += "&";
}
params += QString(paramsList[i].at(0).toLocal8Bit().constData())+"="+QUrl::toPercentEncoding(QString(paramsList[i].at(1).toLocal8Bit().constData()));
++i;
}

//invoquer le service web
this->http.clearPendingRequests();

QHttpRequestHeader header("POST", path);
header.setValue("HOST", host);
header.setValue("Cache-Control", "no-cache");
header.setContentType("application/x-www-form-urlencoded");
header.setContentLength(params.length());

this->http.setHost(host);

this->idVerify = this->http.request(header, params.toUtf8());

this->http.closeConnection();
The http is not declared as QHttp http; in .h file (not as pointer) and I've connected it like
connect(&http, SIGNAL(requestFinished(int, bool)), this, SLOT(receive(int, bool)));
After that, I've implemented the functionc receive witch connected to the requestFinished slot like
void Connexion::receive(int id, bool error)
{
if(error)
{
qDebug() << http.errorString();
this->result = http.errorString();
}
else
{
if(id == this->idVerify )
{
QTextCodec *textCodec = QTextCodec::codecForName("utf-8");
QString res = textCodec->toUnicode(this->http.readAll());

QDomDocument doc;
doc.setContent(res);

QDomElement docElem = doc.documentElement();
result = docElem.text();

// fonction à appeler après reception données
startApplication();
}
}
}
Note that in the receive function, I call a function called startApplication and in last one I show a messageBox if the WebService returned an error.
But after displying the messageBox, I wait some time and the my application access to the receive function another time and a second messageBox is shown. If I click Ok on the 2 messages the application crashes.
I've tried some solutions but everytime it does not work :
1. Use http like a pointer and delete it if a have an error but it does'nt work.
2. Using a bool variable to deny the second access to receive function
I wish it is more clair now and anyone can help me.
Best regards.

ChrisW67
20th October 2011, 09:22
Look at the backtrace in your debugger. Which line is actually triggering the seg fault?

You issue the request and immediately command the connection to close (using a obsolete method in the obsolete class!). When do you receive() the requestFinished() signal for the close, and does that happen before you receive the reply to your main request?

The length of the params QString (your Content-length) and the length of that string encoded as UTF8 (i.e. your data payload) are not necessarily the same. For example;


QString a = QString::fromUtf8("Je parle très peu français.");
qDebug() << a << a.length();
QByteArray utf8 = a.toUtf8();
qDebug() << utf8.length() << utf8.toHex();

27 characters encoded in 29 bytes.


4a 65 20 70 61 72 6c 65 20 74 72 c3 a8 73 20 70 65 75 20 66 72 61 6e c3 a7 61 69 73 2e
J e sp p a r l e sp t r è s sp p e u sp f r a n ç a i s .

mourad
21st October 2011, 10:17
Well, I've modified my code and it works now.
1. I've not closed the http connexion (I've seen that it is automatiquely done).
2. I've gotten the request response in the requestFinished slot when the id is equal to the sended resquest.
3. I've used the done slot to call my traitement if there is no error

For more information, you can seen the stateChanged slot.

Regards.