Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. What are the post-processing operations after I manually delete QObject
Qt 6.12 LTS is out! See what's new in the release blog

What are the post-processing operations after I manually delete QObject

Scheduled Pinned Locked Moved Unsolved General and Desktop
11 Posts 4 Posters 1.8k Views
  • 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.
  • K keeplearning

    qt's memory management does more than I imagined.

    for example, in the following two examples, I manually deleted the headerItem, and the treeWidget called the headerItem() function and returned nullptr, indicating that the treeWidget knew that the headerItem was deleted, to ensure the security of the code.

    In the same way, if you manually delete a validator, lineEdit will also return nullptr when you call validator().

    I'm curious about what post-processing operations are done after QObject is deleted.

    Send a QObject::destroyed() signal to notify treeWidget, lineEdit? or QPointer is used to encapsulate the pointer

    #include <QApplication>
    #include <QDebug>
    #include <QLineEdit>
    #include <QIntValidator>
    #include <QGridLayout>
    #include <QTreeWidget>
    #include <QTreeWidgetItem>
    
    int main(int argc, char *argv[])
    {
    	QApplication a(argc, argv);
    
    	QTreeWidget* treeWidget = new QTreeWidget();
    	QTreeWidgetItem* headerItem= new QTreeWidgetItem();
    	treeWidget->setHeaderItem(headerItem);
    	delete headerItem;
    	qDebug()<<treeWidget->headerItem();
    
    	QLineEdit* lineEdit = new QLineEdit();
    	QIntValidator* validator = new QIntValidator();
    	lineEdit->setValidator(validator);
    	delete validator;
    	qDebug()<<lineEdit->validator();
    }
    

    With the example above, I found that qt memory management does more than I thought.

    I'm trying to write a class that contains QObject*, it's important for me to know the official correct way to do it, if you know the inside story, please let me know, thanks

    jsulmJ Offline
    jsulmJ Offline
    jsulm
    Lifetime Qt Champion
    wrote on last edited by
    #2

    @keeplearning Take a look at https://doc.qt.io/qt-6/objecttrees.html
    If you delete a QObject it will also delete all its children.

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

    K 1 Reply Last reply
    1
    • K keeplearning

      qt's memory management does more than I imagined.

      for example, in the following two examples, I manually deleted the headerItem, and the treeWidget called the headerItem() function and returned nullptr, indicating that the treeWidget knew that the headerItem was deleted, to ensure the security of the code.

      In the same way, if you manually delete a validator, lineEdit will also return nullptr when you call validator().

      I'm curious about what post-processing operations are done after QObject is deleted.

      Send a QObject::destroyed() signal to notify treeWidget, lineEdit? or QPointer is used to encapsulate the pointer

      #include <QApplication>
      #include <QDebug>
      #include <QLineEdit>
      #include <QIntValidator>
      #include <QGridLayout>
      #include <QTreeWidget>
      #include <QTreeWidgetItem>
      
      int main(int argc, char *argv[])
      {
      	QApplication a(argc, argv);
      
      	QTreeWidget* treeWidget = new QTreeWidget();
      	QTreeWidgetItem* headerItem= new QTreeWidgetItem();
      	treeWidget->setHeaderItem(headerItem);
      	delete headerItem;
      	qDebug()<<treeWidget->headerItem();
      
      	QLineEdit* lineEdit = new QLineEdit();
      	QIntValidator* validator = new QIntValidator();
      	lineEdit->setValidator(validator);
      	delete validator;
      	qDebug()<<lineEdit->validator();
      }
      

      With the example above, I found that qt memory management does more than I thought.

      I'm trying to write a class that contains QObject*, it's important for me to know the official correct way to do it, if you know the inside story, please let me know, thanks

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #3

      @keeplearning
      Have you read Object Trees & Ownership?

      QObjects have parent and children.
      Documentation also talks about ownership, e.g.
      void QTreeWidget::setHeaderItem(QTreeWidgetItem *item)

      The tree widget takes ownership of the item.

      You should not be sending QObject::destroyed() signals. Delete the objects manually/automatically as appropriate. Qt will take care of the correct memory management, you should not need to know "the inside story".

      1 Reply Last reply
      1
      • jsulmJ jsulm

        @keeplearning Take a look at https://doc.qt.io/qt-6/objecttrees.html
        If you delete a QObject it will also delete all its children.

        K Offline
        K Offline
        keeplearning
        wrote on last edited by
        #4

        @jsulm
        I know that qt uses object trees for memory management. But what I'm curious about is that in the above example, the code is also safe after manually removing QObject.

        I'm trying to design a container to contain QObject*, here's my simplified code:

        class Item:public QObject{
        	Q_OBJECT
        	// do something
        };
        
        class ItemList:public QObject{
        	Q_OBJECT
        public:
        	ItemList(){}
        	void addItem(Item*);
        	void removeItem(Item*);
        private:
        	QList<Item*> list;
        };
        
        void ItemList::addItem(Item* item){
        	if(item==nullptr){
        		return;
        	}
        	if(list.contains(item)){
        		return;
        	}
        	list.append(item);
        
        }
        
        void ItemList::removeItem(Item* item){
        
        	for(auto iter= list.begin();iter != list.end();iter++){
        		if(*iter==item){
        			list.erase(iter);
        		}
        	}
        
        }
        

        When an Item* is manually deleted externally, the ItemList needs to know about this to avoid accessing the freed memory.

        I came up with two solutions to this:

        1. wrap the Item* with QPointer inside the ItemList,This methodcould avoids accessing the freed memory, but the downside is that elements in QList are still there.
        2. emit destroyed signal to notify the ItemList when the Item is deleted,This method could solve problem, but it adds a bit of time overhead.

        this is why I want to know "the inside story".

        Looking forward to your next reply

        jsulmJ 1 Reply Last reply
        0
        • K keeplearning

          @jsulm
          I know that qt uses object trees for memory management. But what I'm curious about is that in the above example, the code is also safe after manually removing QObject.

          I'm trying to design a container to contain QObject*, here's my simplified code:

          class Item:public QObject{
          	Q_OBJECT
          	// do something
          };
          
          class ItemList:public QObject{
          	Q_OBJECT
          public:
          	ItemList(){}
          	void addItem(Item*);
          	void removeItem(Item*);
          private:
          	QList<Item*> list;
          };
          
          void ItemList::addItem(Item* item){
          	if(item==nullptr){
          		return;
          	}
          	if(list.contains(item)){
          		return;
          	}
          	list.append(item);
          
          }
          
          void ItemList::removeItem(Item* item){
          
          	for(auto iter= list.begin();iter != list.end();iter++){
          		if(*iter==item){
          			list.erase(iter);
          		}
          	}
          
          }
          

          When an Item* is manually deleted externally, the ItemList needs to know about this to avoid accessing the freed memory.

          I came up with two solutions to this:

          1. wrap the Item* with QPointer inside the ItemList,This methodcould avoids accessing the freed memory, but the downside is that elements in QList are still there.
          2. emit destroyed signal to notify the ItemList when the Item is deleted,This method could solve problem, but it adds a bit of time overhead.

          this is why I want to know "the inside story".

          Looking forward to your next reply

          jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #5

          @keeplearning said in What are the post-processing operations after I manually delete QObject:

          the ItemList needs to know about this to avoid accessing the freed memory

          Why? If ItemList just stores pointers in a list then I don't see any problems. Or do you want to do more inside ItemList? Are you dereferencing the pointers somewhere in ItemList?

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

          K 1 Reply Last reply
          0
          • jsulmJ jsulm

            @keeplearning said in What are the post-processing operations after I manually delete QObject:

            the ItemList needs to know about this to avoid accessing the freed memory

            Why? If ItemList just stores pointers in a list then I don't see any problems. Or do you want to do more inside ItemList? Are you dereferencing the pointers somewhere in ItemList?

            K Offline
            K Offline
            keeplearning
            wrote on last edited by
            #6

            @jsulm The Item* pointer inside the ItemList may be manually deleted outside of the ItemList.

            jsulmJ 1 Reply Last reply
            0
            • K keeplearning

              @jsulm The Item* pointer inside the ItemList may be manually deleted outside of the ItemList.

              jsulmJ Offline
              jsulmJ Offline
              jsulm
              Lifetime Qt Champion
              wrote on last edited by
              #7

              @keeplearning That is clear. But what would be the problem then? As long as ItemList does not access the items nothing bad will happen, that is my point.

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

              K 1 Reply Last reply
              0
              • jsulmJ jsulm

                @keeplearning That is clear. But what would be the problem then? As long as ItemList does not access the items nothing bad will happen, that is my point.

                K Offline
                K Offline
                keeplearning
                wrote on last edited by
                #8

                @jsulm The ItemList I gave is a simplified example, and the ItemList may manipulate Item*, such as accessing objectName()

                QString ItemList::getobjectByIndex(int index){
                    if(index>=0&&index<list.count()){
                         return list[i]->objectName(); // list[i] maybe deleted already
                    }else{
                         return nullptr;
                    }
                }
                
                jsulmJ 1 Reply Last reply
                0
                • K keeplearning

                  @jsulm The ItemList I gave is a simplified example, and the ItemList may manipulate Item*, such as accessing objectName()

                  QString ItemList::getobjectByIndex(int index){
                      if(index>=0&&index<list.count()){
                           return list[i]->objectName(); // list[i] maybe deleted already
                      }else{
                           return nullptr;
                      }
                  }
                  
                  jsulmJ Offline
                  jsulmJ Offline
                  jsulm
                  Lifetime Qt Champion
                  wrote on last edited by
                  #9

                  @keeplearning You can prevent others from deleting Item by making Item destructor private and ItemList friend of Item:

                  class ItemList;
                  
                  class Item
                  {
                      Item() {}
                  private:
                      ~Item() {}
                  friend ItemList;
                  };
                  
                  class ItemList
                  {
                  public:
                      ItemList(){}
                      ~ItemList()
                      {
                          for (Item* item : list) {
                              delete item;
                          }
                      }
                      void addItem() { list.append(new Item()); }
                      Item* at(int index) { return list.at(index); }
                  
                  private:
                      QList<Item*> list;
                  };
                  

                  Now, only ItemList can delete Item.

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

                  K 1 Reply Last reply
                  0
                  • jsulmJ jsulm

                    @keeplearning You can prevent others from deleting Item by making Item destructor private and ItemList friend of Item:

                    class ItemList;
                    
                    class Item
                    {
                        Item() {}
                    private:
                        ~Item() {}
                    friend ItemList;
                    };
                    
                    class ItemList
                    {
                    public:
                        ItemList(){}
                        ~ItemList()
                        {
                            for (Item* item : list) {
                                delete item;
                            }
                        }
                        void addItem() { list.append(new Item()); }
                        Item* at(int index) { return list.at(index); }
                    
                    private:
                        QList<Item*> list;
                    };
                    

                    Now, only ItemList can delete Item.

                    K Offline
                    K Offline
                    keeplearning
                    wrote on last edited by
                    #10

                    @jsulm
                    I understand what you're doing, but your approach causes the Item to only be used inside the ItemList, I'm trying to achieve is that the Item can be used externally, and when the Item is deleted, the ItemList won't go wrong.

                    As the example I gave at the beginning, treeWidget->headerItem()return nullptr and doesn't error when you delete headerItem, and lineEdit->validator() doesn't go wrong when you delete validator.

                    So I wonder what was done after validator was deleted, so that lineEdit could know validator was deleted.

                    The method of implementing ItemList can be referred to in its practice.

                    Christian EhrlicherC 1 Reply Last reply
                    0
                    • K keeplearning

                      @jsulm
                      I understand what you're doing, but your approach causes the Item to only be used inside the ItemList, I'm trying to achieve is that the Item can be used externally, and when the Item is deleted, the ItemList won't go wrong.

                      As the example I gave at the beginning, treeWidget->headerItem()return nullptr and doesn't error when you delete headerItem, and lineEdit->validator() doesn't go wrong when you delete validator.

                      So I wonder what was done after validator was deleted, so that lineEdit could know validator was deleted.

                      The method of implementing ItemList can be referred to in its practice.

                      Christian EhrlicherC Offline
                      Christian EhrlicherC Offline
                      Christian Ehrlicher
                      Lifetime Qt Champion
                      wrote on last edited by Christian Ehrlicher
                      #11

                      @keeplearning said in What are the post-processing operations after I manually delete QObject:

                      So I wonder what was done after validator was deleted, so that lineEdit could know validator was deleted.

                      Since those are all QObjects it's easy - the other classes simply connect to QObject::destroyed().
                      But tbh it really depends on what you want to do with that items. Do you even need to store them as pointer?

                      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                      Visit the Qt Academy at https://academy.qt.io/catalog

                      1 Reply Last reply
                      1

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt
                      • Unsolved