我在試圖刪除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