Qt Forum

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

    Solved memory management

    General and Desktop
    4
    8
    317
    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.
    • ODБOï
      ODБOï last edited by

      hello,

      In one QObject derived class I have a loop where i dinamically create Obj objects (QObject derived) , set attributes and add them to a member container (QVariantList) using QVariant::fromValue

      myObjectList.clear() // QVariantList
      // loop
      Obj*o = new Obj(this); //             
      o->setValue(6);
      myObjectList.append(QVariant::fromValue(o)); // myObjectList is a  QVariantList  type member variable
      // endloop
      emit myObjectListChanged()
      

      every time i enter this method/loop i need to empty myObjectList and re-create the Obj objects to store them back in my list.

      But calling myObjectList.clear() will not delete the Obj* objects ? is that right?
      Obj objects will only be deleted when this is deleted because i create them like this Obj*o = new Obj(this); ?

      thank you

      jsulm kshegunov 3 Replies Last reply Reply Quote 0
      • jsulm
        jsulm Lifetime Qt Champion @ODБOï last edited by

        @ODБOï said in memory management:

        But calling myObjectList.clear() will not delete the Obj* objects ? is that right?

        Yes

        You can use https://doc.qt.io/qt-5/qtalgorithms.html#qDeleteAll-1

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        J.Hilk 1 Reply Last reply Reply Quote 3
        • J.Hilk
          J.Hilk Moderators @jsulm last edited by

          @jsulm does QVariant::fromValue return a copy of the pointer in this case ? and is there an implicit back conversion ?
          Or does calling delete on a Variant from a pointer actually call delete on the pointer and not on the QVariant !?

          Lots of magic going on here 🙈

          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct

          Qt Needs YOUR vote: https://bugreports.qt.io/browse/QTQAINFRA-4121


          Q: What's that?
          A: It's blue light.
          Q: What does it do?
          A: It turns blue.

          jsulm 1 Reply Last reply Reply Quote 2
          • jsulm
            jsulm Lifetime Qt Champion @J.Hilk last edited by

            @J-Hilk Good question. I'm not sure. But this can be easily tested with a debug output in Obj destructor :-)

            https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply Reply Quote 2
            • kshegunov
              kshegunov Moderators @ODБOï last edited by

              @ODБOï said in memory management:

              But calling myObjectList.clear() will not delete the Obj* objects ? is that right?

              Yes.

              Obj objects will only be deleted when this is deleted because i create them like this Obj*o = new Obj(this); ?

              Or explicitly, or via a signal-slot connection, but yes.

              @J-Hilk said in memory management:

              does QVariant::fromValue return a copy of the pointer in this case ?

              It does.

              and is there an implicit back conversion ?

              I don't believe so. Back convert to what? QObject *, void *, int *?

              Or does calling delete on a Variant from a pointer actually call delete on the pointer and not on the QVariant !?

              You can test this, but as QVariant or any other Qt type I'm aware of doesn't overload the delete operator I imagine you're going to get a compile-time error.

              Read and abide by the Qt Code of Conduct

              1 Reply Last reply Reply Quote 3
              • kshegunov
                kshegunov Moderators @ODБOï last edited by kshegunov

                @ODБOï
                Something I forgot to ask, why not keep the object list as a regular one (e.g. QList<QObject *>) and put the QVector/QList in the variant whenever you need to?

                Read and abide by the Qt Code of Conduct

                ODБOï 1 Reply Last reply Reply Quote 2
                • J.Hilk
                  J.Hilk Moderators last edited by

                  ok, ok, I see 😜

                  I'll go and test it myself...

                  class MyObj : public QObject
                  {
                      Q_OBJECT
                  public:
                      explicit MyObj (QObject *parent = nullptr) : QObject(parent){}
                      ~MyObj() {
                          qDebug("Destroy ME!!!!");
                      }
                  };
                  
                  
                  int main(int argc, char *argv[])
                  {
                  
                      Q_UNUSED(argc);
                      Q_UNUSED(argv);
                  
                      QVariantList myVariantList;
                  
                      for(int i{0},j{10}; i < j; i++)
                          myVariantList.append(QVariant::fromValue(new MyObj()));
                  
                      qDeleteAll(myVariantList);
                      qDebug("End of main");
                  //    QApplication app(argc, argv);
                  //    return a.exec();
                  }
                  
                  #include "main.moc"
                  

                  results int he compiler error: cannot delete expression of type 'const QVariant'

                  Well, so we'll have to use our own deleteall. One that also clears, as that is what we actually want. Delete & Clear:

                  class MyObj : public QObject
                  {
                      Q_OBJECT
                  public:
                      explicit MyObj (QObject *parent = nullptr) : QObject(parent){}
                      ~MyObj() override {
                          qDebug("Destroy ME!!!!");
                      }
                  };
                  
                  template <typename Class>
                  inline void deleteAllAndClear(QVariantList &list)
                  {
                      for(const QVariant &v : list){
                          delete  qvariant_cast<Class*>(v);
                      }
                      list.clear();
                  }
                  
                  int main(int argc, char *argv[])
                  {
                  
                      Q_UNUSED(argc)
                      Q_UNUSED(argv)
                  
                      QVariantList myVariantList;
                  
                      for(int i{0},j{10}; i < j; i++)
                          myVariantList.append(QVariant::fromValue(new MyObj()));
                  
                      qDebug() << "size of list" << myVariantList.size();
                  
                      deleteAllAndClear<MyObj>(myVariantList);
                  
                      qDebug() << "size of list" << myVariantList.size();
                  
                      qDebug("End of main");
                  //    QApplication app(argc, argv);
                  //    return a.exec();
                  }
                  
                  #include "main.moc"
                  

                  Output:

                  size of list 10
                  Destroy ME!!!!
                  Destroy ME!!!!
                  Destroy ME!!!!
                  Destroy ME!!!!
                  Destroy ME!!!!
                  Destroy ME!!!!
                  Destroy ME!!!!
                  Destroy ME!!!!
                  Destroy ME!!!!
                  Destroy ME!!!!
                  size of list 0
                  End of main

                  Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct

                  Qt Needs YOUR vote: https://bugreports.qt.io/browse/QTQAINFRA-4121


                  Q: What's that?
                  A: It's blue light.
                  Q: What does it do?
                  A: It turns blue.

                  1 Reply Last reply Reply Quote 2
                  • ODБOï
                    ODБOï @kshegunov last edited by

                    hi
                    Thank you very much for all your inputs

                    @kshegunov said in memory management:

                    Something I forgot to ask, why not keep the object list as a regular one (e.g. QList<QObject *>) and put the QVector/QList in the variant whenever you need to?

                    You are right it much simpler to have a member QList<QObject *> and return QVariant list only when i need it.
                    Thats what i did.

                    Thank you

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