我有一段用于填充表格的代码。它在磁盘上打开一个文件并将数据抛出到表中。
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
的{{1}}(看到here)会占用setItem
指针。
如果可能,我想为QStandardItem
和tempModel
修复此问题。我在这里做错了什么?
答案 0 :(得分:1)
内存泄漏不是由于QStandardItem
所有权造成的。 setItem()
方法取得QStandardItem
个对象的所有权,当QStandardItemModel
对象被释放时,这些对象将自动释放。
您的内存泄漏是由tableView->setModel(tempModel);
语句引起的,因为该方法不取得所有权。当您更改模型或释放视图时,您有责任释放模型。
有关详细信息,请参阅this document。
例如:
QItemSelectionModel *m = tableView->selectionModel();
tableView->setModel(tempModel);
delete m;
答案 1 :(得分:0)
我在头文件和主窗口的初始化列表中设置了一个QStandardItemModel
。
<强> myapp.h 强>
...
QStandardItemModel* mainModel;
...
<强> MyApp.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);
清除模型并重新使用它会减少,但不会修复内存泄漏。