Qt5新信号到lambda连接内存泄漏 [英] Qt5 new signal to lambda connections memory leak

查看:1155
本文介绍了Qt5新信号到lambda连接内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

新的Qt5信号和插槽语法允许我们不仅将信号连接到插槽,而且连接到普通的旧函数和函子/ lambda。现在的问题是,lambdas是必需的对象with()运算符,当你连接信号到他们,他们被复制到qt内部类的某个地方。并且,当您从该函数断开信号时,它保留在qt内部。我不明白,是正常的行为吗?或者也许有一种方法可以在断开连接后破坏这些功能对象?

The new Qt5 signals and slots syntax allows us to connect signals not only to slots, but also to plain old functions and functors/lambdas. Now the problem is, that lambdas are essentialy objects with () operator, and when you connect signals to them, they get copied somewhere in qt internal classes. And, when you disconnect the signal from that functor, it stays in qt internals. I fail to understand, is that a normal behaviour? Or maybe there is a way to destroy those functional objects after disconnection?

这里有一个例子:

//example

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QTimer* timer = new QTimer();

    QSharedPointer<QMetaObject::Connection> connection(new QMetaObject::Connection());

    //functor is created and gets copied inside qt internals, connection variable is captured
    //inside the functor

    *connection.data() = QObject::connect(timer, &QTimer::timeout, [=]
    {
        qDebug() << "disconnected";
        QObject::disconnect(*connection.data());
    });

    timer->start(10000);

    return a.exec();
}

//example

连接变量的强引用计数在插槽断开后,它保持2,这意味着函子对象本身仍然活着并且很好,虽然它现在对我没有用。

Now when i look at strong reference count of connection variable after the slot disconnection, it stays 2, which means that the functor object itself is still alive and well, though it is of no use to me now. Do I miss something?

推荐答案

示例被过度设计(为什么使用QSharedPointer? ?)。但确实Qt泄漏函子对象。

The example is over-engineered (why using a QSharedPointer? why capturing it by value?). But indeed Qt is leaking the functor object.

问题在于内部连接列表被简单地标记为脏,并且在发送者被删除或者连接了新的信号之前不被清除(参见< a href =http://code.woboq.org/qt5/qtbase/src/corelib/kernel/qobject.cpp.html#_ZN14QObjectPrivate20cleanConnectionListsEv> cleanConnectionLists )。

The point is that the internal connection list is simply marked as dirty, and not cleared until either the sender is deleted or a new signal is connected (see the usages of cleanConnectionLists).

我推了几个补丁,应该修正这种行为: https://codereview.qt-project。 org /#change,42976 和42979

I pushed a couple of patches that should fix this behaviour: https://codereview.qt-project.org/#change,42976 and 42979

这篇关于Qt5新信号到lambda连接内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆