c++ - 使用临时数据表修复内存泄漏(堆与堆栈)

标签 c++ qt memory-leaks

我有一段用于填充表格的代码。它在磁盘上打开一个文件并将数据放入表中。

if (file.open(QIODevice::ReadOnly))
    {
      QDataStream stream(&file);
      qint32 numRows, numColumns;
      stream >> numRows >> numColumns;
      QStandardItemModel* tempModel = new QStandardItemModel;
      tempModel->setRowCount(numRows);
      tempModel->setColumnCount(numColumns);

      for (int i = 0; i < numRows ; ++i) {
        for (int j = 0; j < numColumns; j++) {
          QStandardItem* tempItem = new QStandardItem; // stored in heap
          tempItem->read(stream);
          tempModel->setItem(i, j, tempItem);
        }
      }
      file.close();
      tableView->setModel(tempModel);
      ...
    }

此代码有效。但我遇到的问题是,我打开的文件越多,使用的内存就越多,而且它永远不会下降。例如,如果我添加第二个文件,我就不需要再存储前一个文件的模型。我想删除它。

我猜内存没有被释放,因为它从未被删除,因为我使用了 new 关键字和一个指针。

如果我们以 tempItem for 循环为例,我想我必须做类似的事情来修复它:

      for (int i = 0; i < numRows ; ++i) {
        for (int j = 0; j < numColumns; j++) {
          //QStandardItem* tempItem = new QStandardItem;
          QStandardItem tempItem; // store on stack and delete at end of scope
          //tempItem->read(stream);
          tempItem.read(stream);
          tempModel->setItem(i, j, tempItem);
        }

但即便如此,它仍会抛出错误,因为 QStandardItemModelsetItem(参见 here)采用 QStandardItem 指针。

如果可能的话,我想为 tempModeltempItem 修复这个问题。我在这里做错了什么?

最佳答案

内存泄漏不是由于 QStandardItem 所有权造成的。 setItem() 方法获取 QStandardItem 对象的所有权,当 QStandardItemModel 对象被释放时,该对象将被自动释放。

您的内存泄漏是由于 tableView->setModel(tempModel); 语句造成的,因为该方法不会取得所有权。当您更改模型或释放 View 时,您有责任释放模型。

参见 this document了解详情。

例如:

QItemSelectionModel *m = tableView->selectionModel();
tableView->setModel(tempModel);
delete m;

关于c++ - 使用临时数据表修复内存泄漏(堆与堆栈),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47113059/

相关文章:

c - Valgrind 崩溃并给我这个无效的 realloc 警告

c++ - 通过自定义分隔符从文件中读取对象数组

c++ - cmake 与 cl : invalid numeric argument '/Wno-uninitialized'

c++ - Qt Creator 中只有有限的工具链

c++ - 如何在 Qt 中为文本编辑程序实现 "Do you want to save changes?"对话框?

swift - SceneKit切换场景内存泄漏

c++ - 是什么导致了这个与模板相关的编译错误?

c++ - 远程过程调用

c++ - 如果自定义类型作为常量从 C++ 传递,如何使用 QML 注册自定义类型

delphi - 如何在 Delphi 10.3.3 中访问 TWebBrowser.Document 时克服内存泄漏