使用临时数据表修复内存泄漏(堆与堆栈)
Fixing memory leak with temporary data table (heap vs stack)
我有一段用于填充表的代码。它会在磁盘上打开一个文件并将数据扔到表中。
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);
}
但即便如此,它也会抛出一个错误,因为QStandardItemModel
的setItem
(见这里)需要一个QStandardItem
指针。
如果可能的话,我想为tempModel
和tempItem
解决这个问题。我在这里做错了什么?
内存泄漏不是由于QStandardItem
所有权造成的。setItem()
方法获取QStandardItem
对象的所有权,当释放QStandardItemModel
对象时,将自动释放这些对象。
内存泄漏是由于 tableView->setModel(tempModel);
语句造成的,因为该方法不具有所有权。更改模型或释放视图时,您负责释放模型。
有关详细信息,请参阅此文档。
例如:
QItemSelectionModel *m = tableView->selectionModel();
tableView->setModel(tempModel);
delete m;
我最终在我的头文件和主窗口的初始化列表中设置了一个QStandardItemModel
。
MyApp.h
...
QStandardItemModel* mainModel;
...
米亚普.cpp
...
MyApp::MyApp(QWidget* parent)
: QMainWindow(parent),
mainModel(new QStandardItemModel(tableView)),
...
我更改了应用程序的工作方式,以便我的表视图只需要一个模型。每当我需要添加新数据集来填充表时,我都会完全清除当前表,创建一个新的临时模型,然后将临时模型设置为主模型。
mainTableModel->clear();
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();
tempItem->read(stream);
tempModel->setItem(i, j, tempItem);
}
}
file.close();
mainModel = tempModel;
tableView->setModel(mainModel);
清除模型并重用它可以减少内存泄漏,但不能修复内存泄漏。
相关文章:
- valgrind-hellgrind与泄漏检查的结果不同
- 从构造函数抛出异常时如何克服内存泄漏
- malloc() 可能出现内存泄漏
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 算法问题:查找从堆栈中弹出的所有序列
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- 尽管遵循了规则,内存泄漏在哪里
- 为什么调用堆栈数组会导致内存泄漏
- gdb错误:Backtrace已停止:上一帧与此帧相同(堆栈已损坏?)
- 我的堆栈弹出式磁带的实现是否泄漏内存?
- terminateThRead()在线程上使用CloseHandle(),仅使用堆栈普通变量(不使用planc)会泄漏内
- 使用临时数据表修复内存泄漏(堆与堆栈)
- 堆栈上的内存泄漏
- C 内存泄漏错误在实现堆栈类时
- 堆栈/队列 C++ 中的内存泄漏
- 可视化泄漏检测器(VLD)显示空的调用堆栈
- 使用模板链表的C++堆栈-内存泄漏
- 在C/ c++中,链表只有头指针分配在堆栈中,其他节点分配在堆中.这可能导致内存泄漏
- 堆栈分配的数组是否可能发生内存泄漏