首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QNetworkRequest导致内存损坏

QNetworkRequest导致内存损坏
EN

Stack Overflow用户
提问于 2020-10-13 03:20:38
回答 1查看 110关注 0票数 0

我创建了一个库,它将处理所有HTTP请求并以JSON格式解析响应数据。当我调用主应用程序中包含get请求的方法(使用GUI)时,我收到了一个内存损坏错误。因此,我添加了QEventLoop和计时器,以等待响应,然后再继续到其他进程。我能够通过调用QNetworkReply.readall()获得响应数据。我需要获得响应数据的char*值,所以我调用了QNetworkReply.data(),但是它是空的。为什么?

下面是我写的代码:

库,它处理HTTP请求:

代码语言:javascript
复制
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();
}

主要GUI应用程序:

代码语言:javascript
复制
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
}

下面是使用QEventLoop的代码:

代码语言:javascript
复制
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_;
}

我期待来自HTTP命令的响应数据:"{"count":3,“code”:“x00000A”,"x00000B","x00000C"}“

Problem:实现这一点的最佳方法是什么?我想把所有的HTTP请求放在一个库中,然后用GUI将它称为我的主要应用程序。请注意:

  • 当我在库中使用QEventLoop等待响应时,QNetworkReply.data()是空的。我需要QNetworkReply.data()的值来解析.
  • 当我不使用QEventLoop并且只使用信号和插槽时(如上面的代码所示),在执行HTTP命令后,主应用程序中会发生内存损坏。没有收到响应数据。
EN

回答 1

Stack Overflow用户

发布于 2020-10-14 14:20:56

建议:

永远不要对QObject使用直接删除。坏:

代码语言:javascript
复制
delete pReply;
delete pManager_;

Qt方式,很好:

代码语言:javascript
复制
pReply->deleteLater();
pManager->deleteLater();

更好:没有“新”(动态内存)

代码语言:javascript
复制
QNetworkAccessManager Manager_;
...
connect(&Manager_, SIGNAL(finished(QNetworkReply*)),&loop, SLOT(quit()));
 
..
pReply->deleteLater();
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64327997

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档