将 'ui.listView->setModel(new QStringListModel(list));' 导致内存泄漏

would `ui.listView->setModel(new QStringListModel(list));` result in a memory leak

本文关键字:内存 泄漏 list QStringListModel gt listView- setModel new ui      更新时间:2023-10-16

嗨,我目前正在学习QT。我正在使用以下代码

QStringList list;
list << "item1" << "item2" << "item3" << "item4" << "item5";
ui.listView->setModel(new QStringListModel(list));

现在我的理解是ui.listView->setModel是作为对堆上对象的引用传递的。难道不需要删除这个对象吗?有什么建议我应该在这里使用升压安全指针吗?因为每次我更新列表的内容时,我都必须调用最后一条语句来更新显示。

很难从这么少的可用代码中判断出来,但是的,您正在堆上创建一个对象,该对象的地址可能会丢失,因此有可能发生内存泄漏。您应该为自己定义一个指向对象的全局指针,并在需要新指针时为其定义delete
更好的方法是创建一个小的class,其中包含对当前QStringListModel的引用,并定义一些方法来创建新的方法,同时删除旧的方法。

class ListModelHolder {
 private:
    QStringListModel* model;
 public:
    ListModelHolder() { model = 0; }
    ~ListModelHolder() { if(model != 0) delete model; }
    set_model(QStringListModel* model) { this->model = model; }
    delete_model() { if(this->model) delete this->model; this->model = 0; }  
  };

举个例子。您可以将此对象保持在全局范围内,也可以根据需要保持全局性。

是的,在这种情况下,您应该删除新的QStringListModel(列表(,但如果您稍微更改代码,它将由您的列表完成View:

ui.listView->setModel(new QStringListModel(list, ui.listView));

QListView::setModel不拥有模型或选择模型的所有权,除非模型的父级是listview。这是因为一个模型可以在几个不同的视图之间共享。这意味着通常由您来处理模型的生命并手动删除它。

我建议您自己管理,使用指向类中模型的指针。这也将使您能够修改模型使用的字符串列表。