QStandardItemModel & Deleting
-
Hi, I have a QStandardItemModel and I append rows to it by creating a pointer QStandardItem and I append that to the model.
when I clear the model with model.clear() the items get removed from the model but the allocated space in ram doesn't get back to the OS (Linux). It seems like the items don't get removed. what am I doing wrong?for (int i=0; i<musicLoader->albumRowCount(); ++i) { QString itemAlbum = musicLoader->albumValue(i,0); QString itemArtist = musicLoader->albumValue(i,1); QString itemText = QString ("%1\n%2").arg(itemAlbum).arg(itemArtist); QPixmap itemIcon(musicLoader->albumValue(i,4)); if (itemIcon.isNull()) itemIcon = style.defaultArtwork; itemIcon = itemIcon.scaled(maxImageSize,Qt::IgnoreAspectRatio,Qt::SmoothTransformation); QStandardItem *item = new QStandardItem(itemIcon,itemText); item->setData(0,Qt::UserRole); item->setData(itemAlbum,Qt::UserRole+1); item->setData(itemArtist,Qt::UserRole+2); for (int j=0; j<musicLoader->albumTrackRowCount(i); ++j) { QString insideItemTitle = musicLoader->albumData(i,j,musicLoader->TITLE); QString insideItemArtist = musicLoader->albumData(i,j,musicLoader->ARTIST); int insideItemTrack = musicLoader->albumData(i,j,musicLoader->TRACK).toInt(); QString itemText = QString("%1\t%2").arg(QString::number(insideItemTrack),insideItemTitle); QStandardItem *insideItem = new QStandardItem(itemText); insideItem->setData(1,Qt::UserRole); insideItem->setData(insideItemTrack,Qt::UserRole+1); insideItem->setData(insideItemTitle,Qt::UserRole+2); insideItem->setData(insideItemArtist,Qt::UserRole+3); item->appendRow(insideItem); } albumModel.appendRow(item); }
-
Hi, I have a QStandardItemModel and I append rows to it by creating a pointer QStandardItem and I append that to the model.
when I clear the model with model.clear() the items get removed from the model but the allocated space in ram doesn't get back to the OS (Linux). It seems like the items don't get removed. what am I doing wrong?for (int i=0; i<musicLoader->albumRowCount(); ++i) { QString itemAlbum = musicLoader->albumValue(i,0); QString itemArtist = musicLoader->albumValue(i,1); QString itemText = QString ("%1\n%2").arg(itemAlbum).arg(itemArtist); QPixmap itemIcon(musicLoader->albumValue(i,4)); if (itemIcon.isNull()) itemIcon = style.defaultArtwork; itemIcon = itemIcon.scaled(maxImageSize,Qt::IgnoreAspectRatio,Qt::SmoothTransformation); QStandardItem *item = new QStandardItem(itemIcon,itemText); item->setData(0,Qt::UserRole); item->setData(itemAlbum,Qt::UserRole+1); item->setData(itemArtist,Qt::UserRole+2); for (int j=0; j<musicLoader->albumTrackRowCount(i); ++j) { QString insideItemTitle = musicLoader->albumData(i,j,musicLoader->TITLE); QString insideItemArtist = musicLoader->albumData(i,j,musicLoader->ARTIST); int insideItemTrack = musicLoader->albumData(i,j,musicLoader->TRACK).toInt(); QString itemText = QString("%1\t%2").arg(QString::number(insideItemTrack),insideItemTitle); QStandardItem *insideItem = new QStandardItem(itemText); insideItem->setData(1,Qt::UserRole); insideItem->setData(insideItemTrack,Qt::UserRole+1); insideItem->setData(insideItemTitle,Qt::UserRole+2); insideItem->setData(insideItemArtist,Qt::UserRole+3); item->appendRow(insideItem); } albumModel.appendRow(item); }
@shahriar25
Hello,
Try this simple test:QPointer<QStandardItem> item = new QStandardItem(QStringLiteral("testitem")); albumModel.appendRow(item); albumModel.clear(); if (item) qDebug() << "Item is not deleted!"; else qDebug() << "Item is deleted!";
And see what you get in the output pane/terminal window.
Kind regards.
-
Hi,
@kshegunov I think that the question is rather: why after a call to delete doesn't the OS available memory increase.
Note that you can't use QPointer with QStandardItem, it's not a QObject based class.
AFAIK, a delete doesn't mean that the memory will instantly be returned to the OS. It might be marked as free but kept in the application's "memory pool" for later re-use.
-
Hi,
@kshegunov I think that the question is rather: why after a call to delete doesn't the OS available memory increase.
Note that you can't use QPointer with QStandardItem, it's not a QObject based class.
AFAIK, a delete doesn't mean that the memory will instantly be returned to the OS. It might be marked as free but kept in the application's "memory pool" for later re-use.
@SGaist said:
I think that the question is rather: why after a call to delete doesn't the OS available memory increase.
I got that but a few weeks ago I already had this discussion in this forum.
The short answer would be: "It does" :)AFAIK, a delete doesn't mean that the memory will instantly be returned to the OS. It might be marked as free but kept in the application's "memory pool" for later re-use.
Depends on the heap manager implementation, but generally it does. However, Linux eats up all the memory and caches it, so depending on the inspection tool it might not be directly obvious.
For example my Debian has exactly at this moment:
KiB Mem : 16383400 total, 681720 free, 2975152 used, 12726528 buff/cache681MB free is a joke for 16GB physical memory, but see the cache? It basically means the OS has appropriated all the memory and cached it, so it's owning it and distributing as it sees fit. That's the reason I posted the test code. If pointer is NULL then everything is fine. :)
-
Hi @kshegunov
I tried what you said but I got these errors:
tried this:
QPointer<QStandardItem> item = new QStandardItem(QStringLiteral("testitem"));got these:
/home/shahriar/Qt5.6.0/5.6/gcc_64/include/QtCore/qsharedpointer_impl.h:705: error: no matching function for call to 'QtSharedPointer::ExternalRefCountData::getAndRef(QStandardItem*&)'
inline QWeakPointer(X *ptr, bool) : d(ptr ? Data::getAndRef(ptr) : Q_NULLPTR), value(ptr)
^/home/shahriar/Qt5.6.0/5.6/gcc_64/include/QtCore/qsharedpointer_impl.h:705: error: cannot convert 'QStandardItem*' to 'QObject*' in initialization
inline QWeakPointer(X *ptr, bool) : d(ptr ? Data::getAndRef(ptr) : Q_NULLPTR), value(ptr)
^and it points ti this line:
inline QWeakPointer(X *ptr, bool) : d(ptr ? Data::getAndRef(ptr) : Q_NULLPTR), value(ptr)what is this?
-
Hi @kshegunov
I tried what you said but I got these errors:
tried this:
QPointer<QStandardItem> item = new QStandardItem(QStringLiteral("testitem"));got these:
/home/shahriar/Qt5.6.0/5.6/gcc_64/include/QtCore/qsharedpointer_impl.h:705: error: no matching function for call to 'QtSharedPointer::ExternalRefCountData::getAndRef(QStandardItem*&)'
inline QWeakPointer(X *ptr, bool) : d(ptr ? Data::getAndRef(ptr) : Q_NULLPTR), value(ptr)
^/home/shahriar/Qt5.6.0/5.6/gcc_64/include/QtCore/qsharedpointer_impl.h:705: error: cannot convert 'QStandardItem*' to 'QObject*' in initialization
inline QWeakPointer(X *ptr, bool) : d(ptr ? Data::getAndRef(ptr) : Q_NULLPTR), value(ptr)
^and it points ti this line:
inline QWeakPointer(X *ptr, bool) : d(ptr ? Data::getAndRef(ptr) : Q_NULLPTR), value(ptr)what is this?
@shahriar25
Hi,what is this?
Well, it is me being stupid. The errors are because
QStandardItem
doesn't derive fromQObject
(which it shouldn't). Forget that code and look at my previous post (responding to SGaist) for the "explanation", sorry for misleading you! -
Well @kshegunov
this code prints Not Deleted!!! :QStandardItem *item = new QStandardItem("Row 1!!!"); model.appendRow(item); model.clear(); if (item) cout<<"Not Deleted!!!"<<endl; else cout<<"Deleted!!!"<<endl;
So item doesn't get deleted;
I have about ten models and each one of them take about 200mb ram so I Want to clear the old model before showing a new one . when I load and clear three models one after another gnome system monitor shows the app uses 1gb memory!!! (the sum of the memory of three models)
-
Well @kshegunov
this code prints Not Deleted!!! :QStandardItem *item = new QStandardItem("Row 1!!!"); model.appendRow(item); model.clear(); if (item) cout<<"Not Deleted!!!"<<endl; else cout<<"Deleted!!!"<<endl;
So item doesn't get deleted;
I have about ten models and each one of them take about 200mb ram so I Want to clear the old model before showing a new one . when I load and clear three models one after another gnome system monitor shows the app uses 1gb memory!!! (the sum of the memory of three models)
So item doesn't get deleted
i can assure you it does - here. But in any case, what's your Qt version?
this code prints Not Deleted!!!
As expected. The difference between
QPointer
and raw pointer (which you're using in your last snippet) is thatQPointer
is set to NULL when theQObject
is deleted. This is not the case for raw pointers. So even if the item is deleted youritem
variable will still point to the same memory address, thus this code will always print "Not Deleted".Kind regards.
-
Well @kshegunov
Then have nothing to worry about and there is no memory leak. Thank you both @kshegunov & @SGaist.
I'm uisng Qt 5.6 -
Try this:
Here I was adding 4 standardItem in one row starting from column 1.
The same I am deleting before clearing the Model.
m_qsimAlarmModel is my object of QStandardItemModel.Below code is not tested, some change may required.
for (int i = 0; i<m_qsimAlarmModel->rowCount();i++)
{
QStandardItem *test = nullptr;
test = m_qsimAlarmModel->takeItem(i,1);
delete test;
test = nullptr;
test = m_qsimAlarmModel->takeItem(i,2);
delete test;
test = nullptr;
test = m_qsimAlarmModel->takeItem(i,3);
delete test;
test = nullptr;
test = m_qsimAlarmModel->takeItem(i,4);
delete test;
test = nullptr;}