Yip*_*Yay 9 c++ memory qt memory-leaks shared-ptr
我最近开始为自己调查Qt并提出以下问题:
假设我有一些QTreeWidget* widget.在某些时刻,我想添加一些项目,这是通过以下调用完成的:
QList<QTreeWidgetItem*> items;
// Prepare the items
QTreeWidgetItem* item1 = new QTreeWidgetItem(...);
QTreeWidgetItem* item2 = new QTreeWidgetItem(...);
items.append(item1);
items.append(item2);
widget->addTopLevelItems(items);
Run Code Online (Sandbox Code Playgroud)
到目前为止它看起来还不错,但我实际上并不了解谁应该控制对象的生命周期.我应该用一个例子解释一下:
让我们说,另一个函数调用widget->clear();.我不知道这个调用下面会发生什么,但我确实认为,内存分配item1和item2没有得到安置在这里,因为他们的OWNAGE实际上并没有转移.而且,砰的一声,我们有内存泄漏.
问题如下 - 确实Qt可以为这种情况提供一些东西吗?我可以使用boost::shared_ptr或任何其他智能指针,并写出类似的东西
shared_ptr<QTreeWidgetItem> ptr(new QTreeWidgetItem(...));
items.append(ptr.get());
Run Code Online (Sandbox Code Playgroud)
但我不知道Qt本身是否会尝试delete对我的指针进行显式调用(因为我将它们声明为shared_ptr管理状态,这将是灾难性的).
你会如何解决这个问题?也许一切都很明显,我想念一些非常简单的东西?
快速浏览qtreewidget.cpp可以看到:
void QTreeWidget::clear()
{
Q_D(QTreeWidget);
selectionModel()->clear();
d->treeModel()->clear();
}
void QTreeModel::clear()
{
SkipSorting skipSorting(this);
for (int i = 0; i < rootItem->childCount(); ++i) {
QTreeWidgetItem *item = rootItem->children.at(i);
item->par = 0;
item->view = 0;
delete item; // <<----- Aha!
}
rootItem->children.clear();
sortPendingTimer.stop();
reset();
}
Run Code Online (Sandbox Code Playgroud)
所以看起来你对widget-> addTopLevelItems()的调用确实会导致QTreeWidget获得QTreeWidgetItems的所有权.所以你不应该自己删除它们,或者将它们保存在shared_ptr中,否则你最终会遇到双删除问题.