QThread内存泄漏



main.cpp:

#include <QCoreApplication>
#include <QtCore>
#include "myobject.h"
QThread* cThread;
MyObject* cObject;
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    cThread = new QThread();
    cObject = new MyObject();
    cObject->moveToThread(cThread);
    QObject::connect(cThread, SIGNAL(started()),
                     cObject, SLOT(doWork()));
    QObject::connect(cThread, SIGNAL(finished()),
                     cThread, SLOT(deleteLater()));
    QObject::connect(cThread, SIGNAL(finished()),
                     cObject, SLOT(deleteLater()));
    cThread->start();
    return a.exec();
}

myobject.cpp:

#include "myobject.h"
MyObject::MyObject(QObject *parent) :
    QObject(parent)
{
}
void MyObject::doWork()
{
    qDebug() << "Hi";
    QThread::currentThread()->quit();
    return;
}

myobject.h:

#ifndef MYOBJECT_H
#define MYOBJECT_H
#include <QtCore>
class MyObject : public QObject
{
    Q_OBJECT
public:
    explicit MyObject(QObject *parent = 0);
signals:
public slots:
    void doWork();
};
#endif // MYOBJECT_H

显然,根据:https://stackoverflow.com/a/16062717,内存泄漏,但我该如何修复?我想我必须返回事件循环,然后调用quit?但问题是我无法访问事件循环。

没有内存泄漏。如果你坚持使用它的对象模型、对象树和所有权,Qt确实可以很好地清理。我也喜欢下面的例子。

以下是您引用的示例,并在deleteLater()上添加了观察结果。

main.cpp

#include <QCoreApplication>
#include <QtCore>
#include <QThread>
class MyThread : public QThread
{
    Q_OBJECT
public slots:
    void deleteLater()
    {
        qDebug() << Q_FUNC_INFO;
        QThread::deleteLater();
    }
};

class MyObject : public QObject
{
    Q_OBJECT
public:
    explicit MyObject(QObject *parent = 0){}
signals:
public slots:
    void deleteLater()
    {
        qDebug() << Q_FUNC_INFO;
        QObject::deleteLater();
    }
    void doWork()
    {
        qDebug() << "Hi";
        QThread::currentThread()->quit(); // It is supposed to stop here, but it doesn't.
        return;
        for (int i = 0; i < 1000000; i++) {
            qDebug() << i;
        }
    }
};
QThread* cThread;
MyObject* cObject;
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    cThread = new MyThread();
    cObject = new MyObject();
    cObject->moveToThread(cThread);
    QObject::connect(cThread, SIGNAL(started()),
                     cObject, SLOT(doWork()));
    QObject::connect(cThread, SIGNAL(finished()),
                     cThread, SLOT(deleteLater()));
    QObject::connect(cThread, SIGNAL(finished()),
                     cObject, SLOT(deleteLater()));
    cThread->start();
    return a.exec();
}

输出:

Hi
void __thiscall MyObject::deleteLater(void)
void __thiscall MyThread::deleteLater(void)

希望能有所帮助。

我是链接上的海报。事实上,默认连接没有内存泄漏。通过对deleteLater和像@phyatt这样的析构函数进行子类化,您获得了:

Hi 
void MyObject::deleteLater() 
virtual MyObject::~MyObject()  Being deleted 
void MyThread::deleteLater() 
virtual MyThread::~MyThread()  Being deleted 

但如果你在连接中使用Qt::QueueConnection,你会得到:

Hi 
void MyThread::deleteLater() 
virtual MyThread::~MyThread()  Being deleted 

并且对象CCD_ 3被泄漏。

当线程有效地退出时,它是未记录的。因此,我无法争辩这种行为是否永远都是一样的。一种可能性是让线程启动器负责执行清理工作。例如:

 void cleanup(){
  cThread->exit();
  cThread->wait();
  delete cThread;
  delete cObject;
 }

要结束一切,您不必使用此代码修复任何内容。

相关内容

  • 没有找到相关文章

最新更新