PDA

View Full Version : Qt memory handling



Skizmo
17th November 2008, 11:27
Hi,

Since I've been using Qt, there has always been 1 big question on my mind and it's about how Qt handles new/deletes. The biggest problem I have is that the Qt-help gives you a lot of information you don't need, but doesn't give you the answers you are looking for (to be honest, I think that this is a big mistake of the help-builder guys).

For instance, I'm using a QTabWidget and I'm dynamically inserting tab pages. Each tab page needs his own widget. Nowhere in the help I can find who deletes this widget. Is Qt deleting this widget after destruction, or am I responsible for it ? In this case it's with a QTabWidget, but I have this problem with a lot of other Qt objects. The help files give you no clue at all on how to handle these kind of allocations. Is there any logic on how to know when I need to delete a object, or when Qt is deleting it for me ?

lyuts
17th November 2008, 12:18
...
For instance, I'm using a QTabWidget and I'm dynamically inserting tab pages. Each tab page needs his own widget. Nowhere in the help I can find who deletes this widget. Is Qt deleting this widget after destruction, or am I responsible for it ? In this case it's with a QTabWidget, but I have this problem with a lot of other Qt objects. The help files give you no clue at all on how to handle these kind of allocations. Is there any logic on how to know when I need to delete a object, or when Qt is deleting it for me ?

I will disagree with you. Qt help contains a part called "Object Trees and Object Ownership" which says:

"Construction/Destruction Order of QObjects
When QObjects are created on the heap (i.e., created with new), a tree can be constructed from them in any order, and later, the objects in the tree can be destroyed in any order. When any QObject in the tree is deleted, if the object has a parent, the destructor automatically removes the object from its parent. If the object has children, the destructor automatically deletes each child. No QObject is deleted twice, regardless of the order of destruction."

This answers your question about QTabWidget and your pages.

Skizmo
17th November 2008, 12:42
Ah !

Thanx, apparently I didn't dig enough into the help files. I'm going to look into it :cool:

caduel
17th November 2008, 12:54
Yes, but the more interesting question is: if you create a QWidget (let's say: unparented) with new and then insert it to a QTabWidget with QTabWidget::insertTab(), will the QTabWidget take ownership?

(In all probability it will, but still I like it if a function that gets passed a pointer, explicitly states that/if it will take ownership. In this case the docs do not make a statement which might leave you wonder - esp. if you are not that experienced with Qt.)

wysota
17th November 2008, 13:02
Yes, but the more interesting question is: if you create a QWidget (let's say: unparented) with new and then insert it to a QTabWidget with QTabWidget::insertTab(), will the QTabWidget take ownership?

The answer is logically trivial. A widget occupies part of its parent's rectangle. Hence if you see the widget inside the tab widget, it has to be owned by it. Hence it gets destroyed when the tab widget is deleted. There are no exceptions to this rule. Note that if you remove the tab from the tab widget before deleting the tab widget, the tab will not get deleted.

lyuts
17th November 2008, 13:08
Here is the answer to your question:



tabWidget = new QTabWidget(this);

btn = new QPushButton;

tabWidget->addTab(btn, tr("newTab"));

qDebug() << tabWidget;
qDebug() << btn->parent()->parent();



prints this


QTabWidget(0x51a33a0)
QTabWidget(0x51a33a0)


btn's parent is QStackedWidget, while the QStackedWidget's parent is tabWidget.

QPlace
17th November 2008, 23:48
Another question from that category (I already asked it in this forum but did not get a response) is who is responsible for deleting instances that QNetworkManager passes to the client with "readytoread" or smth (I don' remember syntax exactly). In short, the slot receives the pointer to an instance that is used to retrieve the data. Who is responsible for deleting this allocation?

wysota
18th November 2008, 07:43
The parent :) As homework, the check of who is the parent of QNetworkReply is left to you. By the way, remember you can always explicitly delete an object yourself, regardless of who is its parent. Just don't do that from within a slot (if you have to, use QObject::deleteLater()).

caduel
18th November 2008, 09:33
Maybe you can delete QWidgets.
QObjects ... not always. E.g. the model in a QAbstractItemView is (or maybe was) held by a raw pointer and thus the view does (or did) not realize if you destroyed the model.
(I suggested to the trolls that this should be 'fixed' as we are spoilt by Qt to usually be able to destroy QObjects.)

wysota
18th November 2008, 10:46
I'm not sure you are right. The fact that there is a regular pointer doesn't yet mean there is something wrong. A QObject emits a signal before getting destroyed, so the view can still react on the object being deleted. If it's not implemented, you can do that yourself :)

caduel
18th November 2008, 11:07
That is correct, of course. A raw pointer does not implicate any trouble by itself.

Checking my emails I must correct myself (a bit): the issue was destroying a sourcemodel of a QAbstractItemProxyModel.
The view does notice when it's model is deleted, the proxy, however, does (or did) not.
I deleted the old model and got a crash.
(Since then I am a bit more careful what QObjects I may delete while they are in use somewhere (by Qt).)