QNetworkRequest导致内存损坏

如何解决QNetworkRequest导致内存损坏

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

这是我写的代码

处理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> & )),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主应用程序:

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的代码

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_,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 get命令获得以下响应数据: “ {” count“:3,”代码“:[” x00000A“,” x00000B“,” x00000C“]}”“

问题: 实现此目的的最佳方法是什么?我想将所有HTTP请求都放在一个库中,然后使用GUI将其称为我的主应用程序。请注意:

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

解决方法

建议:

请勿对QObject使用直接删除。不好:

delete pReply;
delete pManager_;

Qt方式,很好:

pReply->deleteLater();
pManager->deleteLater();

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

QNetworkAccessManager Manager_;
...
connect(&Manager_,SIGNAL(finished(QNetworkReply*)),&loop,SLOT(quit()));
 
..
pReply->deleteLater();

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?