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?
Forum Updated to NodeBB v4.3 + New Features

Memory Leak or Not?

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 3 Posters 1.0k 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