Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Qt5至lambda连接的新信号内存泄漏_C++_C++11_Signals_Qt5_Slot - Fatal编程技术网

C++ Qt5至lambda连接的新信号内存泄漏

C++ Qt5至lambda连接的新信号内存泄漏,c++,c++11,signals,qt5,slot,C++,C++11,Signals,Qt5,Slot,新的Qt5信号和插槽语法使我们不仅可以将信号连接到插槽,还可以连接到普通的旧函数和functor/lambda。现在的问题是,lambda本质上是带有()运算符的对象,当您将信号连接到它们时,它们会被复制到qt内部类的某个地方。而且,当你从那个函子上断开信号时,它保持在qt内部。我不明白,这是正常的行为吗?或者有没有办法在断开连接后销毁这些功能对象 下面是一个例子: //example int main(int argc, char *argv[]) { QApplication a(

新的Qt5信号和插槽语法使我们不仅可以将信号连接到插槽,还可以连接到普通的旧函数和functor/lambda。现在的问题是,lambda本质上是带有()运算符的对象,当您将信号连接到它们时,它们会被复制到qt内部类的某个地方。而且,当你从那个函子上断开信号时,它保持在qt内部。我不明白,这是正常的行为吗?或者有没有办法在断开连接后销毁这些功能对象

下面是一个例子:

//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
//示例
int main(int argc,char*argv[])
{
质量保证申请a(argc、argv);
QTimer*定时器=新的QTimer();
QSharedPointer连接(新的QMetaObject::connection());
//functor被创建并复制到qt内部,连接变量被捕获
//函子内部
*connection.data()=QObject::connect(计时器和QTimer::超时,[=]
{
qDebug()开始(10000);
返回a.exec();
}
//范例

现在,当我在插槽断开连接后查看连接变量的强引用计数时,它保持为2,这意味着函子对象本身仍然是活动的,尽管它现在对我没有任何用处。我是否遗漏了什么?

该示例设计过度(为什么要使用QSharedPointer?为什么要通过值捕获它?).但实际上Qt正在泄漏函子对象

关键是,内部连接列表只是标记为脏的,并且在删除发送方或连接新信号之前不会清除(请参阅的用法)


我推了几个补丁来修复这个行为:和42979

当你破坏计时器时会发生什么?我也这么想过,但是引用计数仍然保持为2=/如果我不将连接变量存储在该'*connection.data()中,它将变为1的唯一方式='分离并删除计时器。这仍然很奇怪。我已经有一段时间没有使用Qt了,但是你不能使用返回的
QMetaObject::Connection
,使用相同的参数重新连接吗?这可以解释为什么它保留对函数的引用。我认为没有重新连接的方法。从源代码中,disconnect()将接收器设置为0。因此无法恢复连接。我认为OP确实发现了内存泄漏。请提交错误报告。是的,我知道它可能有点设计过度,但我需要共享指针,以便能够轻松监视对它的引用数,查看functor对象是否仍然存在,我确实有一个类似的逻辑不在主函数中的项目,所以我不能在那里通过引用捕获连接。