Qt中的内存管理

10

我对Qt内存管理有些疑惑。

以Listview为例,我们在Listview中通过动态分配内存来添加每个项。那么在这种情况下,我们需要手动删除所有已分配的内存吗?

例如:

Qlistview *list = new Qlistview;
QStandardItemModel  *mModel = new QStandardItemModel();
list ->setModel(mModel);

for(int I =0;i<10;i++)
{
QsandardItem *item = new QsandardItem(“Hi”);
mModel->appendRow(item);
}
在这个例子中,是否需要手动删除item?

找出答案的一种可靠方法是查看代码。 - shoosh
呃,这是一项繁琐的工作 :) - Naruto
1
Qt文档通常会说明某个对象是否接管了传递的对象。但是在QStandardItemModel的情况下,并非所有地方都有提到(例如,对于setItem()有提到,但对于appendRow()则没有)。 - Frank Osterfeld
相关的编程内容(包括详细回答)请参考以下链接:https://dev59.com/e3E95IYBdhLWcg3wCJRf/ - AlQuemist
2个回答

16

QStandardItemModel会接管其所包含的项目,因此它们在模型被销毁时会自动删除。但您仍然需要手动删除模型本身(setModel()不会将模型所有权转移给视图,因为一个模型可以被多个视图使用)。


0

同意chalup的答案,你问题的答案是: 如果你调用了mModel->clear();,它将帮助你删除所有这些项,你不需要手动逐个删除项,更重要的是,如果你想完全删除模型,你应该调用delete mModel;

运行ChrisW67提供的示例代码here,你会有更好的理解:

#include <QCoreApplication>
#include <QDebug>
#include <QStandardItemModel>

class MyItem: public QStandardItem
{
public:
    MyItem(const QString & text): QStandardItem(text) {
        qDebug() << "Item created" << this;
    }
    ~MyItem()     {
        qDebug() << "Item destroyed" << this;
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QStandardItemModel* model = new QStandardItemModel;
    for (int row = 0; row < 4; ++row) {
        for (int column = 0; column < 4; ++column) {
            QStandardItem *item =
                new MyItem(QString("row %0, column %1").arg(row).arg(column));
            model->setItem(row, column, item);
        }
    }

    qDebug() << "Finished making model";
    model->clear();
    qDebug() << "Model cleared";
    qDebug() << "===================";
    QStandardItem *newitem1 = new MyItem(QString("new item"));
    qDebug()<<"create new item at"<<newitem1;
    QStandardItem *newitem2 = new MyItem(QString("new item"));
    QStandardItem *newitem3 = new MyItem(QString("new item"));
    QStandardItem *newitem4 = new MyItem(QString("new item"));
    //because we didn't delete model so far, we can still append items to model.
    model->appendRow({newitem1,newitem2,newitem3,newitem4});
    model->clear();
    qDebug() << "Model cleared again";

    //although the memoty of newitem1 has already been deallocated, but the pointer still point to that address, now newitem1 is a dangling pointer
    if(newitem1){
        qDebug()<<"newitem1 address is"<<newitem1;
    }
    else{
        qDebug()<<"newitem1 address in null";
    }
//    delete newitem1;//this will cause program crash because newitem1 acutally has been delete, double delete should not be allowed
    newitem1 = nullptr;//Instead of delete, wo could set newitem1 pointet to null, this can avoid wild pinter/dangling pointer
    delete model;
    qDebug()<<"deleted model";
    return a.exec();

我也在学习C++,如果上面有什么错误,请告诉我,我会进行修正。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接