Вопрос

I'm making a program that uses lots of timer and, at intervals of 4 seconds, does an online post to a php script. I'm coding in QtCreator 5.1. I use classes just like the ones below.

The one below just populates a task list, but throughout the course of 8 to 12 hours, the memory that the program takes up just keep rising and rising gradually.

What am I doing wrong while using this class? I have to be able to keep posting online like I already am, about every 4 to 8 seconds.

Here's a simple class for taking care of one of my processes:

Header file: 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`

Source file: 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);
}
Это было полезно?

Решение

From the Qt docs http://qt-project.org/doc/qt-5.1/qtnetwork/qnetworkaccessmanager.html

Note: After the request has finished, it is the responsibility of the user to delete the QNetworkReply object at an appropriate time. Do not directly delete it inside the slot connected to finished(). You can use the deleteLater() function.

I would suggest calling reply->deleteLater() in your replyFinished() method.

Другие советы

You should call deleteLater() for an QNetworkReply object after use.

Note: After the request has finished, it is the responsibility of the user to delete the QNetworkReply object at an appropriate time. Do not directly delete it inside the slot connected to finished(). You can use the deleteLater() function.

More information here: http://harmattan-dev.nokia.com/docs/library/html/qt4/qnetworkaccessmanager.html

Thank you everyone for the hel. It was very simply the "deleteLater()" on the reply in the

void replyFinished(QNetworkReply *reply)
{

}

and it should have looked like this

void replyFinished(QNetworkReply *reply)
{
    // after all of your processing 
    reply->deleteLater();
}

it was such a small problem but one that drove me crazy for a long time so i hope this helps

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top