我在试图删除QTreeWidgetItem
的代码中遇到一个奇怪的问题。特别是,我有这个在我的课:SegFault删除QTreeWidgetItem
std::map<int, std::unique_ptr<QTreeWidgetItem>> mymap;
当我关闭应用程序,我有段错误,该unique_ptr
的默认析构函数中。于是,我尝试将问题分解,和我创建一个析构函数执行以下操作:
~MyClass() {
for (auto x = mymap.begin(); x != mymap.end(); x++ ) {
QTreeWidgetItem* temp = x->second.release();
qDebug() << "make sure the pointer is not broken " << temp->isDisabled();
delete temp;
}
}
的调用函数isDisabled()
是没用的,只是为了确保指针不破。那么,我可以使用指针中的对象,但是当我尝试删除它时,我有SegFault。
有什么建议吗?感谢大家
为什么你需要首先将'QTreeWidgetItems'作为'unique_ptrs'存储? 'QTreeWidgetItem'被设计成具有'QTreeWidget'作为它的父项,因此这个父窗口小部件将负责在合适的时候删除这些项目。在你的情况下最有可能发生的事情是双重免费的,因为树零件项的两个所有者:'QTreeWidget'和'unique_ptr'。确保你了解Qt的[亲子关系和内存管理](http://doc.qt.io/qt-5/objecttrees.html)。 – Dmitry
Hi @Dmitry,感谢您的评论。那么我明白这个用法可能会很奇怪,但它应该起作用。在[doc](http://doc.qt.io/qt-5/qtreewidgetitem.html)中,QTreeWidgetItem不是'QObject'。无论如何,在你的链接中,它被写为“当在堆上创建QObject时(即用新创建的),可以以任意顺序从它们构建一棵树,随后树中的对象可以在任何订单“,我使用'new'来创建它。最后,在这种情况下,我期望Qt尝试删除父项时使用SegFault,但不会在我的行'delete temp'中。我是否犯了一些错误? – n3mo
确实,'QTreeWidgetItem'不是'QObject',但类似的原理适用于'QTreeWidget'和'QTreeWidgetItem'。 'QTreeWidget'的析构函数[doc](https://doc.qt.io/qt-5/qtreewidget.html#dtor.QTreeWidget)表示它“销毁了树部件及其所有项目”。为什么segfault发生在'delete temp'上很难说。检查“QTreeWidget”在那一刻是否还活着。如果不是,你正在做同样的指针的第二次删除,因此崩溃。调用'temp-> isDisabled()'什么都不检查:如果它已经被删除,它只是未定义的行为 - 它可能会崩溃或者它可能不会。 – Dmitry