[Qt-interest] does QT have a garbage collector ?

Oliver.Knoll at comit.ch Oliver.Knoll at comit.ch
Wed Mar 4 19:55:30 CET 2009


Jesús Fernández wrote on Monday, March 02, 2009 11:29 AM:

> If you give a parent to the QObject you can forget the deletion of
> the object. When the parent is removed all the childs are removed. 

This yields the following "corollary" (yeah, I always wanted to use this word for real, ever since university time ;):

  "Be careful who the parent is - especially WHEN it is deleted!"

The canonical case (which actually happened to me a few years ago ;) is a simple QFileDialog which is opened whenever you activate the "Open" action in some QMainWindow menu:

class MyMainWindow : public QMainWindow {
  Q_OBJECT
  ...
public slots:
  void open();
  ...
};

void MyMainWindow::open() {
  QFileDialog *fileDialog;
  fileDialog = new QFileDialog(this);
  ...
}

Now whenever the user activates "Open" a new QFileDialog is dynamically allocated (for demonstration purposes - also see "stack allocation" below). It has a valid parent QObject (the QMainWindow derived class, "this"). So far so good.

Off course it is very likely that the user calls "Open" several times during the lifetime of the application - and each time a QFileDialog is allocated - obvious. Ehm... and WHEN is it finally deleted? Ah yes, right, as soon as the parent is deleted which happens at... uh... yessss, right, at the very end when the user closes the whole application. Ahaaa....

See where this leads to? While this is not a memory leak in the actual sense (the 'fileDialog' instances ARE finally properly deleted when the application terminates) resources ARE WASTED! You could end up with having 100 QFileDialog instances floating around in memory for nothing - until the application is closed.

By the way, this is also a typical Java problem: the garbage collector can't clean up as long as you have a "dangling reference" (just as we have "dangling pointers" in C++ and Co.) to some top-level object, and a whole rat tail of objects might hence never be deallocated!


So better:

void MyMainWindow::open() {
  QFileDialog *fileDialog;
  fileDialog = new QFileDialog(this);
  // select some file
  ...
  // explicitly delete the unused resources
  delete fileDialog;
}

Or even better, allocate on the stack:

void MyMainWindow::open() {
  // automatic variable (aka "allocate on stack")
  QFileDialog fileDialog;
  ...
}

The later (allocate on stack) might not always be possible/desireable.

Also note that you can ALWAYS explicitly delete a QObject based object, even when it has a valid parent! The QObject model will make sure that the object being deleted informs its parent first, so it does NOT get deleted twice when the parent is eventually deleted.


All this is very easy, but you have to grasp the concept behind it once. Also read the excellent Qt docs about the "Qt Object Model" here:

  http://doc.trolltech.com/4.5/object.html

And specifically here:

  http://doc.trolltech.com/4.5/objecttrees.html


Cheers, Oliver
-- 
Oliver Knoll
Dipl. Informatik-Ing. ETH
COMIT AG - ++41 79 520 95 22



More information about the Qt-interest-old mailing list