QT网络崩溃

QT Networking Crashes

本文关键字:崩溃 网络 QT      更新时间:2023-10-16

我在访问网络请求的回复对象时得到了sigsegv。如果我这样做,它可以正常工作:

QNetworkAccessManager manager;
/**
 * Main entry point.
 */
int main(int argc, char *argv[])
{
    Configuration configuration;
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    QNetworkRequest * req = new QNetworkRequest(QUrl("http://localhost:5000/status/health"));
    QNetworkReply * reply = manager.get(*req);
    QObject::connect(reply, &QNetworkReply::finished, [&]{
        QByteArray read = reply->readAll();
        std::string readStr = read.toStdString();
        std::cout << "Got reply: " << readStr << endl;
        reply->close();
        reply->deleteLater();
    });
    return a.exec();
}

,但这会做一个sigsegv:

QNetworkAccessManager manager;
void doRequest() {
    QNetworkRequest * req = new QNetworkRequest(QUrl("http://localhost:5000/status/health"));
    QNetworkReply * reply = manager.get(*req);
    QObject::connect(reply, &QNetworkReply::finished, [&]{
        QByteArray read = reply->readAll();
        std::string readStr = read.toStdString();
        std::cout << "Got reply: " << readStr << endl;
        reply->close();
        reply->deleteLater();
    });
}

/**
 * Main entry point.
 */
int main(int argc, char *argv[])
{
    Configuration configuration;
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    doRequest();
    return a.exec();
}

所以有些范围掉了。我不知道什么。所以我这样做了:

static QNetworkReply * reply;
void doRequest() {
    QNetworkRequest req(QUrl("http://localhost:5000/status/health"));
    reply = manager.get(req);
    QObject::connect(reply, &QNetworkReply::finished, [&]{
        QByteArray read = reply->readAll();
        std::string readStr = read.toStdString();
        std::cout << "Got reply: " << readStr << endl;
        reply->close();
        reply->deleteLater();
    });
}

这不是sigsegv。而且我不知道为什么不。

我真的很愚蠢地对Lambdas如何使用[&amp;]?还是对qnetworkreply对象的真正是神奇的?这真的是一个明智的指针,因为它脱离了范围,因此被摧毁了吗?

有人有指向从我的GUI中调用网络函数的方法吗?我正在执行所有操作以使此操作以在单击按钮上工作。也许我需要自己保留答复对象,而忘记了它们在那个lambda中。我不知道。我发现的示例都是独立的,就像我的原始代码一样。

lambdas中的[&amp;]符号确实很危险。特别是在异步环境中。

所以我要告诉你为什么:

QNetworkReply * reply = manager.get(*req);
QObject::connect(reply, &QNetworkReply::finished, [&]{
    QByteArray read = reply->readAll();
    std::string readStr = read.toStdString();
    std::cout << "Got reply: " << readStr << endl;
    reply->close();
    reply->deleteLater();
});

您是通过参考捕获回复指针。在示波器结束时,回复指针被破坏,您可以提及垃圾。

解决方案是按值捕获回复指针:

QNetworkReply * reply = manager.get(*req);
QObject::connect(reply, &QNetworkReply::finished, [reply]{
    QByteArray read = reply->readAll(); // Works well, it's a fresh copy of the pointer
    std::string readStr = read.toStdString();
    std::cout << "Got reply: " << readStr << endl;
    reply->close();
    reply->deleteLater();
});