post 请求和 QNetworkAccessManager 导致内存泄漏

The*_*n68 2 c++ post qt memory-leaks qnetworkaccessmanager

我正在制作一个程序,该程序使用大量计时器,并且每隔 4 秒对php脚本进行在线发布。我正在编码QtCreator 5.1。我使用的类就像下面的类一样。

下面这个只是填充一个任务列表,但在8到12个小时的过程中,程序占用的内存一直在不断上升,逐渐上升。

使用此类时我做错了什么?我必须能够像现在一样继续在网上发帖,大约每 4 到 8 秒一次。

这是一个简单的类,用于处理我的一个流程:

头文件: tasklistprocess.h

#ifndef TASKLISTPROCESS_H
#define TASKLISTPROCESS_H

#include <QThread>
#include <QtCore>
#include <QNetworkRequest>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QListWidget>
#include <QTabWidget>

#include "globalhelper.h"
#include "securityinfo.h"

class TaskListProcess : public QThread
{
    Q_OBJECT
public:
    explicit TaskListProcess(QListWidget *obj_main, QTabWidget *tabs_main, QString user, QObject *parent = 0);

signals:
    void upTaskStorage(int key,QHash<QString,QString> item);

private:
    GlobalHelper gh;
    Securityinfo sci;
    QNetworkAccessManager *nam;
    QNetworkRequest request;
    QByteArray data;

    // this is the disposable params for reusage through out the class
    QUrlQuery params;
    QString post_data;
    QString user_name;
    QTimer *tasklist_tmr;

    bool get_task_list;

    QListWidget *obj;
    QTabWidget *tabs;

private slots:
    void setTaskList();
    void replyFinished(QNetworkReply *reply);
    void sendPost(QString file_name, QUrlQuery params);
};

#endif // TASKLISTPROCESS_H`
Run Code Online (Sandbox Code Playgroud)

源文件: tasklistprocess.cpp

#include "tasklistprocess.h"

TaskListProcess::TaskListProcess(QListWidget *obj_main, QTabWidget *tabs_main, QString user, QObject *parent) :
    QThread(parent)
{
    user_name = user;
    get_task_list = false;
    obj = obj_main;
    tabs = tabs_main;
    tasklist_tmr = new QTimer(this);

    connect(this,SIGNAL(started()),this,SLOT(setTaskList()));
    connect(tasklist_tmr,SIGNAL(timeout()),this,SLOT(setTaskList()));

    nam = new QNetworkAccessManager(this);
    request.setHeader(QNetworkRequest::ContentTypeHeader,"application/x-www-form-urlencoded");
    request.setRawHeader( "User-Agent" , "Mozilla Firefox" );
    // here we connect up the data stream and data reply signals
    connect(nam, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
}

void TaskListProcess::setTaskList()
{
    qDebug() << "Your task list was set";
    bool in = false;
    if(!(tasklist_tmr->isActive()))
    {
        tasklist_tmr->start(10000);
        in = true;
    }
    if(!(get_task_list))
    {
        params.clear();
        params.addQueryItem("user_name", user_name);
        params.addQueryItem("logged_in", "1");
        sendPost("getTaskList.php",params);
        get_task_list = true;
    }
    else
    {
        if(post_data.contains("|*|"))
        {
            //here i retrieve a piece of information from a php script which is stored in a custom string format
            // here we clear the list for the new data to be put in
            if(obj->count()>0)
            {
                obj->clear();
            }
            int key = 0;
            foreach(QString inner_task,post_data.split("|*|"))
            {
                QHash<QString,QString> task_cont;
                //qDebug() << "         ";
                if(inner_task.contains("*,*"))
                {
                    foreach(QString task_val,inner_task.split("*,*"))
                    {
                        if(task_val.contains("*=*"))
                        {
                            QStringList key_pairs = task_val.split("*=*");
                            task_cont.insert(key_pairs[0],key_pairs[1]);
                            if(key_pairs[0] == "tt")
                            {
                                QString val_in;
                                if(key_pairs[1].length()>10)
                                {
                                    // this sets the title to the shortened version
                                    // if the string length is too long
                                    val_in = key_pairs[1].left(10) + "....";
                                }
                                else
                                {
                                    val_in = key_pairs[1];
                                }
                                obj->addItem("Task :" + QString::fromUtf8(key_pairs[1].toStdString().c_str()));
                            }
                        }
                    }
                }
                //task_storage.insert(key,task_cont);
                emit upTaskStorage(key,task_cont);
                key ++;
            }
        }
        get_task_list = false;
    }
    // here we're checking to see if they are looking at the task tab so it doesn't keep changing
    // back and forth between the tabs
    bool change = true;
    if(tabs->currentIndex() != 0)
    {
        change = false;
    }

    if(change)
    {
        tabs->setCurrentIndex(0);
    }else if(in)
    {
        tabs->setCurrentIndex(0);
    }
}

void TaskListProcess::replyFinished(QNetworkReply *reply)
{
    if (reply->error() != QNetworkReply::NoError) {
            qDebug() << "Error in" << reply->url() << ":" << reply->errorString();
            return;
        }
    QString data = reply->readAll().trimmed();
    post_data = data;
    if(get_task_list)
    {
        setTaskList();
    }
}

void TaskListProcess::sendPost(QString file_name, QUrlQuery params)
{
    post_data = "";
    QUrl url(sci.getHost() + file_name);

    url.setQuery(params);

    data.clear();
    data.append(params.toString().toUtf8());

    request.setUrl(url);
    nam->post(request, data);
}
Run Code Online (Sandbox Code Playgroud)

Dan*_*urn 5

来自 Qt 文档http://qt-project.org/doc/qt-5.1/qtnetwork/qnetworkaccessmanager.html

注意:请求完成后,用户有责任在适当的时间删除 QNetworkReply 对象。不要直接在连接到finished()的槽内删除它。您可以使用deleteLater() 函数。

我建议调用reply->deleteLater()您的replyFinished() 方法。