In Qt, a parent is assigned in constructing a QObject. Setting parent to 0 constructs an object with no parent. If the object is a widget, it will become a top-level window. If I create a top-level window on heap, do I need to explicitly delete the top level window to avoid memory leakage? Or Qt will take care of it. If so, when does Qt delete it? At closing the widget or closing the application?
4 Answers
It is my understanding that both of the existing answers are wrong.
When the QApplication is destroyed, the top level widgets are all deleted.
It is true that the QApplication will not return from the event loop until the top level windows are closed, but that has nothing to do with the question.
As long as your QApplication is correctly destroyed (ie created on the stack or otherwise deleted), all widgets will be deleted.
You don't have to delete top level widgets, and not doing so will not result in a leak, technically or otherwise.
(This is not the case for top level QObjects, only QWidgets, which are tracked by QApplication)

- 2,650
- 1
- 16
- 15
a memory leak is when an object is inaccessible by running code but still stored in memory
The short answer is no.The thing is you can access your top level widgets anytime anywhere using
QWidgetList QApplication::topLevelWidgets();
Even if your top level widgets on the heap don't have parents, they are associated with the QApplication
object. And it happens that the lifetime of this object is the lifetime of the program. So even if the QApplication
object doesn't delete the top level widgets, when he is deleted then your process is being terminated. Which means these widgets are going to be deleted soon afterwards.
There is a leak, but it happens between the time you return from main()
and the time your process becomes a zombie. Which is totally fine.
The biggest downside of not freeing top level widgets is that you are going to have false positives using a memory analyzer.
-
Do you mean there is no memory leakage after the application is closed? – user1899020 Apr 08 '14 at 14:44
-
***The OS always get his memory back***. The Issue with memory leaks is that you are running and virtually holding resources you cannot release until you are dead, and that even you cannot use them. – UmNyobe Apr 08 '14 at 14:45
-
But the QApplication object does delete the top level widgets, see my answer. – OliJG Sep 10 '14 at 06:35
-
@OliJG `Do I need to explicitly delete top level windows to avoid memory leakage` I am telling the OP: there is no memory leak from top level widgets as long as the application object exists. Whether he delete them is irrelevant. – UmNyobe Sep 10 '14 at 07:02
-
"There is a leak, but it happens between the time you return from main() and the time your process becomes a zombie." - That is not the case. There is no leak because they are deleted. You will not have false positives using a memory analyzer. – OliJG Sep 12 '14 at 08:33
-
@OliJG you seem to forget that my main point is: whether or not qapplication deletes is irrelevant. Why partially quote? `So even if the QApplication object doesn't delete the top level widgets...` – UmNyobe Sep 12 '14 at 08:55
-
It's not an important issue, that's why I didn't downvote. Still, your last two paragraphs are incorrect, with the last paragraph being problematic IMO. – OliJG Sep 13 '14 at 06:56
For a QWidget, you can set the Qt::WA_DeleteOnClose property so that when the QWidget is closed, its destructor will get called. Which will in-turn call all the child widget's destructors ensuring that any memory analyzer will not show false positives.

- 21
- 1
No, you have to take care of top widgets yourself. If you create application with 2 or more widgets without a parent, you may notice, that when you close main window, other windows are still active and keep running, unless you select different behavior in main widget's closeEvent()
.
If you want to close and delete all other top widgets, you may do so in main widget's closeEvent
(hide()
all other top windows and use deleteLater()
or delete them directly)

- 3,463
- 2
- 26
- 42