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. Memory Leak or Not?
Qt 6.11 is out! See what's new in the release blog

Memory Leak or Not?

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 3 Posters 1.4k 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.
  • N Offline
    N Offline
    Nima Ghorab
    wrote on last edited by
    #1

    Hello guys.
    This is my first post here.
    I came across with simple but important issue on dealing with QObject.
    The problem is:
    I have a simple ContactList class which inherits QObject.
    Here is ContactList.h:

    #ifndef CONTACTLIST_H
    #define CONTACTLIST_H
    
    #include <QObject>
    
    class ContactList : public QObject
    {
        Q_OBJECT
    public:
        explicit ContactList(QObject *parent = nullptr);
        ContactList(const QString& input_name, const QString& input_cellphone, QObject *parent = nullptr);
        ~ContactList();
        inline const QString& getName() const { return name; }
        inline const QString& getCellphone() const { return cellphone; }
    
    signals:
    
    public slots:
    
    private:
        QString name;
        QString cellphone;
    };
    
    #endif // CONTACTLIST_H
    

    ContactList.cpp:

    #include "contactlist.h"
    #include <iostream>
    using namespace std;
    
    ContactList::ContactList(QObject *parent) : QObject(parent)
    {
        cout << "Default ContactList Constructor Called!" << endl;
    }
    
    ContactList::ContactList(const QString &input_name, const QString &input_cellphone, QObject *parent) :
        QObject(parent),
        name(input_name),
        cellphone(input_cellphone)
    {
        cout << "ConstactList Constructor Called!" << endl;
    }
    
    ContactList::~ContactList()
    {
        cout << "ContactList Destructor Called!" << endl;
    }
    

    And finally main.cpp:

    #include <iostream>
    #include <QCoreApplication>
    #include "contactlist.h"
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
    
        {
            QObject* first_data = new ContactList("Jack", "++448294241");
        }
    
        cout << "Seems there is memory leak at above!" << endl;
    
        {
            QObject parent;
            QObject* second_data = new ContactList("Jack", "++448294241", &parent);
        }
    
        cout << "Seems there is no memory leak at above!" << endl;
    
        return 0;
    }
    

    After executing above code I got this:
    ConstactList Constructor Called!
    Seems there is memory leak at above!
    ConstactList Constructor Called!
    ContactList Destructor Called!
    Seems there is no memory leak at above!

    1- Is there any memory leak in this code specially when first_data is created?
    2- If there is no memory leak why I got a less destructor call?
    3- How does QObject detect that currently pointing to a stack or heap allocated object? (this step is very important because of different deletion process on stack or heap)
    Thanks in advance.

    aha_1980A 1 Reply Last reply
    0
    • N Nima Ghorab

      Hello guys.
      This is my first post here.
      I came across with simple but important issue on dealing with QObject.
      The problem is:
      I have a simple ContactList class which inherits QObject.
      Here is ContactList.h:

      #ifndef CONTACTLIST_H
      #define CONTACTLIST_H
      
      #include <QObject>
      
      class ContactList : public QObject
      {
          Q_OBJECT
      public:
          explicit ContactList(QObject *parent = nullptr);
          ContactList(const QString& input_name, const QString& input_cellphone, QObject *parent = nullptr);
          ~ContactList();
          inline const QString& getName() const { return name; }
          inline const QString& getCellphone() const { return cellphone; }
      
      signals:
      
      public slots:
      
      private:
          QString name;
          QString cellphone;
      };
      
      #endif // CONTACTLIST_H
      

      ContactList.cpp:

      #include "contactlist.h"
      #include <iostream>
      using namespace std;
      
      ContactList::ContactList(QObject *parent) : QObject(parent)
      {
          cout << "Default ContactList Constructor Called!" << endl;
      }
      
      ContactList::ContactList(const QString &input_name, const QString &input_cellphone, QObject *parent) :
          QObject(parent),
          name(input_name),
          cellphone(input_cellphone)
      {
          cout << "ConstactList Constructor Called!" << endl;
      }
      
      ContactList::~ContactList()
      {
          cout << "ContactList Destructor Called!" << endl;
      }
      

      And finally main.cpp:

      #include <iostream>
      #include <QCoreApplication>
      #include "contactlist.h"
      
      using namespace std;
      
      int main(int argc, char *argv[])
      {
      
          {
              QObject* first_data = new ContactList("Jack", "++448294241");
          }
      
          cout << "Seems there is memory leak at above!" << endl;
      
          {
              QObject parent;
              QObject* second_data = new ContactList("Jack", "++448294241", &parent);
          }
      
          cout << "Seems there is no memory leak at above!" << endl;
      
          return 0;
      }
      

      After executing above code I got this:
      ConstactList Constructor Called!
      Seems there is memory leak at above!
      ConstactList Constructor Called!
      ContactList Destructor Called!
      Seems there is no memory leak at above!

      1- Is there any memory leak in this code specially when first_data is created?
      2- If there is no memory leak why I got a less destructor call?
      3- How does QObject detect that currently pointing to a stack or heap allocated object? (this step is very important because of different deletion process on stack or heap)
      Thanks in advance.

      aha_1980A Offline
      aha_1980A Offline
      aha_1980
      Lifetime Qt Champion
      wrote on last edited by aha_1980
      #2

      @Nima-Ghorab said in Memory Leak or Not?:

      1- Is there any memory leak in this code specially when first_data is created?

      Yeah, there is a leak for first_data. You create a variable with new but don't delete it.

      3- How does QObject detect that currently pointing to a stack or heap allocated object? (this step is very important because of different deletion process on stack or heap)

      It does not. There is no magic behind. A stack variable is destroyed when it goes out of scope, i.e. at the first closing curly bracket '}' . Therefore the destructor for parent is called, and as second_data is parented to parent, it is destructed as well.

      Regards

      Qt has to stay free or it will die.

      1 Reply Last reply
      5
      • N Offline
        N Offline
        Nima Ghorab
        wrote on last edited by
        #3

        Thank you so much.
        Dear aha_1980, I still get confuse about my third question.
        About my third question, please consider following code:

        #include <iostream>
        #include <QCoreApplication>
        #include "contactlist.h"
        
        using namespace std;
        
        int main(int argc, char *argv[])
        {
        
            {
                QObject first_parent;
                QObject* second_data = new ContactList("Jack", "++448294241", &first_parent);
            }
        
            {
                QObject second_parent;
                ContactList my_friend("John", "++38475887690", &second_parent);
                QObject* third_data = &my_friend;
            }
        
            cout << "Seems there is no memory leak at above!" << endl;
        
            return 0;
        }
        

        Based on what you said I still can't figure it out how first_parent can detect that its child is a heap allocated object and therefore delete it but in second_parent it can detect that its child is a stack allocated object and therefore does not delete it!
        Can you explain a little bit more how QObject works?
        Thank you so much.

        aha_1980A 1 Reply Last reply
        0
        • N Nima Ghorab

          Thank you so much.
          Dear aha_1980, I still get confuse about my third question.
          About my third question, please consider following code:

          #include <iostream>
          #include <QCoreApplication>
          #include "contactlist.h"
          
          using namespace std;
          
          int main(int argc, char *argv[])
          {
          
              {
                  QObject first_parent;
                  QObject* second_data = new ContactList("Jack", "++448294241", &first_parent);
              }
          
              {
                  QObject second_parent;
                  ContactList my_friend("John", "++38475887690", &second_parent);
                  QObject* third_data = &my_friend;
              }
          
              cout << "Seems there is no memory leak at above!" << endl;
          
              return 0;
          }
          

          Based on what you said I still can't figure it out how first_parent can detect that its child is a heap allocated object and therefore delete it but in second_parent it can detect that its child is a stack allocated object and therefore does not delete it!
          Can you explain a little bit more how QObject works?
          Thank you so much.

          aha_1980A Offline
          aha_1980A Offline
          aha_1980
          Lifetime Qt Champion
          wrote on last edited by aha_1980
          #4

          @Nima-Ghorab

          I don't have the complete details about the internal function, but reading ~QObject doc, you must not parent objects that are created on the stack, otherwise your program will crash.

          This implies, that if you give a parent, the object should be on the heap (created with new).

          Regards

          Qt has to stay free or it will die.

          1 Reply Last reply
          5
          • Christian EhrlicherC Offline
            Christian EhrlicherC Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on last edited by Christian Ehrlicher
            #5

            @aha_1980 said in Memory Leak or Not?:

            you should

            read: you must not except you unparent it before condestruction :)

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

            aha_1980A 1 Reply Last reply
            2
            • Christian EhrlicherC Christian Ehrlicher

              @aha_1980 said in Memory Leak or Not?:

              you should

              read: you must not except you unparent it before condestruction :)

              aha_1980A Offline
              aha_1980A Offline
              aha_1980
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @Christian-Ehrlicher Fixed :)

              Qt has to stay free or it will die.

              1 Reply Last reply
              0
              • N Offline
                N Offline
                Nima Ghorab
                wrote on last edited by
                #7

                Thank you so much @aha_1980.

                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