繁体   English   中英

QThread内存泄漏

[英]QThread Memory Leak

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 

并且对象cObject泄漏。

当线程将有效退出时,未记录。 因此,我不能争辩这种行为是否会一直相同。 一种可能性是使线程启动器负责执行清理工作。 例如:

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

总结一下,您无需使用此代码进行任何修复。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM