Memory Leak or Not?
-
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. -
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.@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 withnew
but don'tdelete
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 assecond_data
is parented toparent
, it is destructed as well.Regards
-
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. -
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.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
-
@aha_1980 said in Memory Leak or Not?:
you should
read: you must not except you unparent it before
condestruction :) -
@aha_1980 said in Memory Leak or Not?:
you should
read: you must not except you unparent it before
condestruction :)@Christian-Ehrlicher Fixed :)
-
Thank you so much @aha_1980.