[英]QNetworkRequest causes memory corruption
I created a library which will handle all HTTP requests and parsing of response data in JSON format.我创建了一个库,它将处理所有 HTTP 请求并解析 JSON 格式的响应数据。 When I called the method that includes get request in my main application (with GUI), I received a memory corruption error.当我在主应用程序(使用 GUI)中调用包含 get 请求的方法时,我收到了内存损坏错误。 So I added QEventLoop and a timer to wait for the response before proceeding to other processes.所以我添加了 QEventLoop 和一个计时器来等待响应,然后再继续其他进程。 I was able to get the response data by calling QNetworkReply.readall().我能够通过调用 QNetworkReply.readall() 来获取响应数据。 I needed to get the char* value of the response data so I called the QNetworkReply.data() but it is empty.我需要获取响应数据的 char* 值,所以我调用了 QNetworkReply.data() 但它是空的。 Why?为什么?
Here are the codes I wrote:下面是我写的代码:
Library which handles HTTP requests:处理 HTTP 请求的库:
void HttpRequest::getRequest(string param1, string param2)
{
pManager_ = new QNetworkAccessManager(this);
QUrl cUrl(sampleUrl);
QNetworkRequest request(cUrl);
request.setRawHeader(keyHeader.c_str(), param1.c_str());
connect(pManager_, SIGNAL(finished(QNetworkReply*)), this, SLOT(requestFinished(QNetworkReply*)));
connect(pManager_, SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError> & )), this,
SLOT(handleSslErrors(QNetworkReply*, const QList<QSslError> & )));
cUrl.addQueryItem("name", QString::fromStdString(param2));
pManager_->get(request); // memory corruption error encountered in main application after calling this
std::cout << "after calling get" << std::endl;
}
void HttpRequest::requestFinished(QNetworkReply *pReply)
{
QByteArray responseData;
std::cout << " request finished" << std::endl;
int responseStatus = pReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
std::cout << " status code: " << responseStatus << std::endl;
if(pReply->error())
std::cout << " Error: " << pReply->errorString().toStdString() << std::endl;
else
{
responseData = pReply->readAll();
qDebug() << " Response data: " << responseData;
const char* pResponseData = responseData.data();
qDebug() << "pResponseData: " << pResponseData ;
// parsing here
}
pReply->deleteLater();
pManager_->deleteLater();
}
void HttpRequest::handleSslErrors(QNetworkReply *pReply, const QList<QSslError> & )
{
std::cout << " SSL ERROR" << std::endl;
int responseStatus = pReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
}
Main GUI application:主要图形用户界面应用程序:
DialogTest::DialogTest(QWidget *parent) :
QDialog(parent),
ui(new Ui::DialogTest)
{
// some codes here
if(enabled)
{
HttpRequest::instance()->getInformation(param1, param2); // memory corruption happened here when I called getRequest() method with no event loop
}
// other threads here
}
Here is the code that uses QEventLoop:这是使用 QEventLoop 的代码:
void HttpRequest::getRequest(string param1, string param2)
{
QTimer qTimer;
QEventLoop loop;
pManager_ = new QNetworkAccessManager(this);
QUrl cUrl(sampleUrl);
QNetworkRequest request(cUrl);
request.setRawHeader(keyHeader.c_str(), param1.c_str());
connect(&qTimer,SIGNAL(timeout()),&loop, SLOT(quit()));
connect(pManager_, SIGNAL(finished(QNetworkReply*)),&loop, SLOT(quit()));
QNetworkReply *pReply = pManager_->get(request);
qTimer.start(1000);
loop.exec();
int responseCode = pReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
std::cout << "status code: " << responseCode << std::endl;
if(pReply->error())
{
std::cout << " Error: " << pReply->errorString().toStdString() << std::endl;
}
else
{
qDebug() << "[HttpRequest] Response data: " << pReply->readAll();
QByteArray response = pReply->readAll(); // it printed this value: "{"count":3,"codes":["x00000A","x00000B","x00000C"]}" which is correct
char* pResponseData = response.data();
qDebug() << "pResponseData: " << pResponseData ; //it printed this: pResponseData:
}
delete pReply;
delete pManager_;
}
I am expecting this response data from a HTTP get command: "{"count":3,"codes":["x00000A","x00000B","x00000C"]}"我期待来自 HTTP get 命令的响应数据: "{"count":3,"codes":["x00000A","x00000B","x00000C"]}"
Problem : What is the best way to implement this?问题:实现这一点的最佳方法是什么? I want to put all HTTP request in a library then call it my main application with GUI.我想将所有 HTTP 请求放在一个库中,然后使用 GUI 将其称为我的主应用程序。 Please note that:请注意:
an advice:一个建议:
never use a direct delete for a QObject.永远不要对 QObject 使用直接删除。 BAD:坏的:
delete pReply;
delete pManager_;
Qt way,GOOD: Qt方式,好:
pReply->deleteLater();
pManager->deleteLater();
Better: no "new" (dynamic memory)更好:没有“新”(动态内存)
QNetworkAccessManager Manager_;
...
connect(&Manager_, SIGNAL(finished(QNetworkReply*)),&loop, SLOT(quit()));
..
pReply->deleteLater();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.