删除QObject后,Qt信号仍在触发

时间:2019-06-09 11:45:11

标签: c++ qt segmentation-fault valgrind

我有一个使用Qt的C ++程序,它的GUI QObject具有链接到函数(foo)的ComboBox(简称为bar())。此QObject称为对象A

组合框在构造函数中链接:

  connect(foo, SIGNAL(currentIndexChanged(int)), SLOT(bar(int)));

bar(int)中,此函数在函数末尾被调用:

  inspector->update();

在检查器的update函数中,发生这种情况:

  • A被删除(delete A;,几乎是它是由new创建的)。

  • 创建了一个与A类型相同的新实例,我们称之为对象B

这已初始化并且可以运行一会儿,然后一切都变得非常错误。

程序出现段错误,但仅是由于Qt错误。 GDB并没有多大帮助,但是通过Valgrind memcheck运行程序会产生大量无效读取,例如:

==23410== Invalid read of size 8
==23410==    at 0xFE92D7A: QMetaObject::activate(QObject*, int, int, void**) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.9.5)
==23410==    by 0x79DDC94: QComboBox::currentIndexChanged(QString const&) (in /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5.9.5)
==23410==    by 0x79DFB2D: ??? (in /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5.9.5)
...
==23410==  Address 0x3218ca68 is 8 bytes inside a block of size 48 free'd
==23410==    at 0x4C3123B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23410==    by 0xFE9119A: QObjectPrivate::deleteChildren() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.9.5)
==23410==    by 0x7913D4B: QWidget::~QWidget() (in /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5.9.5)

在我看来,好像foo的信号被再次发送,并试图调用不存在的对象bar()的{​​{1}}。但这怎么可能呢?当然A也应该阻止任何信号通过吗?另外,我只更改一次组合框的值-为什么会发送多个信号?

我尝试了阻止信号,并且尝试了重新整理内容,但没有成功。

这里是整个相关的Valgrind memcheck log

这是Qt的错误吗?还是我做错了什么?非常感谢您提供任何帮助,包括进一步调试的帮助。

1 个答案:

答案 0 :(得分:0)

尝试执行以下操作:

  • 首先将成员searchQuery: "" 添加到您的班级。

  • 在构造函数中,将QMetaObject::Connection foo_barConnect;保存在connect中:

foo_barConnect
  • foo_barConnect = connect(foo, SIGNAL(currentIndexChanged(int)), SLOT(bar(int))); 函数的update()之前添加:
delete
  • 如果您重新// Check if `foo_barConnect` is valid (connected) if(foo_barConnect){ // Disconnect foo_bar connection disconnect(foo_barConnect); } 对象并且需要连接,请不要忘记重新new并将连接存储在connect中。

希望它对您有帮助。