Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • 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
Forum Updated to NodeBB v4.3 + New Features

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

Scheduled Pinned Locked Moved Unsolved General and Desktop
11 Posts 4 Posters 548 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 Offline
    K Offline
    keeplearning
    wrote on last edited by
    #1

    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 JonBJ 2 Replies Last reply
    0
    • 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 Extensions
                        • Unsolved