Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Solved QStandardItemModel & Deleting

    General and Desktop
    4
    10
    6100
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • S
      shahriar25 last edited by

      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);
      }
      
      kshegunov 1 Reply Last reply Reply Quote 0
      • kshegunov
        kshegunov Moderators @shahriar25 last edited by kshegunov

        @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.

        Read and abide by the Qt Code of Conduct

        1 Reply Last reply Reply Quote 0
        • SGaist
          SGaist Lifetime Qt Champion last edited by

          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.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          kshegunov 1 Reply Last reply Reply Quote 0
          • kshegunov
            kshegunov Moderators @SGaist last edited by

            @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/cache

            681MB 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. :)

            Read and abide by the Qt Code of Conduct

            1 Reply Last reply Reply Quote 0
            • S
              shahriar25 last edited by

              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?

              kshegunov 1 Reply Last reply Reply Quote 0
              • kshegunov
                kshegunov Moderators @shahriar25 last edited by kshegunov

                @shahriar25
                Hi,

                what is this?

                Well, it is me being stupid. The errors are because QStandardItem doesn't derive from QObject (which it shouldn't). Forget that code and look at my previous post (responding to SGaist) for the "explanation", sorry for misleading you!

                Read and abide by the Qt Code of Conduct

                1 Reply Last reply Reply Quote 0
                • S
                  shahriar25 last edited by

                  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)

                  kshegunov 1 Reply Last reply Reply Quote 0
                  • kshegunov
                    kshegunov Moderators @shahriar25 last edited by kshegunov

                    @shahriar25

                    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 that QPointer is set to NULL when the QObject is deleted. This is not the case for raw pointers. So even if the item is deleted your item variable will still point to the same memory address, thus this code will always print "Not Deleted".

                    Kind regards.

                    Read and abide by the Qt Code of Conduct

                    1 Reply Last reply Reply Quote 0
                    • S
                      shahriar25 last edited by shahriar25

                      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

                      1 Reply Last reply Reply Quote 0
                      • B
                        Bikram Shishodia last edited by

                        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;

                            }
                        
                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post