Memory Management in Qt
Asked Answered
O

2

10

I have small doubt about Qt memory management.

Let's take an example of Listview, in listview we add each item by allocating memory dynamically. So in this case do we need to delete all the "new"ed items manually.

E.g:

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);
}

In this example, should item be deleted manually?

Orphism answered 26/10, 2010 at 6:13 Comment(4)
One sure way of finding out - look at the code.Pegeen
hmmm, its tedious JOb :)Orphism
The Qt docs often state whether some object takes ownership of a passed object, or not. In the case of QStandardItemModel, it's not mentioned everywhere though (it is for setItem() for example, but not for appendRow())Modestamodeste
related (extended answers): https://mcmap.net/q/209807/-memory-management-in-qtGourmont
C
16

QStandardItemModel takes ownership of items, so they will be automatically deleted when model is destroyed. You still need to delete the model itself (setModel() doesn't transfer ownership of model to the view, because one model can be used by multiple views).

Cheloid answered 26/10, 2010 at 7:2 Comment(0)
R
0

Agree with chalup's answer , the answer for your question is: if you called mModel->clear();, it will help you delele all of those items, you don't need to mannually delete items one by one, what's more if you want to totally delete model, you should called delete mModel;.

Run the example code provided by ChrisW67 here, you will have a better understanding:

#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();

I am learing c++ too, if there is something wrong above, please tell me, i will correct it.

Rill answered 30/5, 2021 at 4:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.