【问题标题】:Memory Management in QtQt 中的内存管理
【发布时间】:2011-04-30 14:02:25
【问题描述】:

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

在这个例子中,是否应该手动删除项目?

【问题讨论】:

  • 找出答案的可靠方法 - 查看代码。
  • 嗯,它的繁琐工作:)
  • Qt 文档经常声明某个对象是否拥有传递对象的所有权。在 QStandardItemModel 的情况下,它并没有在任何地方被提及(例如它是针对 setItem(),但不是针对 appendRow())
  • 相关(扩展答案):stackoverflow.com/q/2491707

标签: c++ qt qt4 nokia


【解决方案1】:

QStandardItemModel 拥有项目的所有权,所以当模型被销毁时它们会被自动删除。您仍然需要删除模型本身(setModel() 不会将模型的所有权转移到视图,因为一个模型可以被多个视图使用)。

【讨论】:

    【解决方案2】:

    同意 chalup 的回答,您的问题的答案是: 如果你打电话给mModel-&gt;clear();,它会帮你删除所有这些项目,你不需要手动一个一个删除项目,如果你想完全删除模型,你应该打电话给delete mModel;

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

    #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++的,如果上面有不对的地方请告诉我,我会改正的。

    【讨论】:

      猜你喜欢
      • 2011-01-30
      • 1970-01-01
      • 1970-01-01
      • 2012-02-27
      • 1970-01-01
      • 2014-06-02
      • 2014-06-05
      • 2019-09-27
      • 1970-01-01
      相关资源
      最近更新 更多