Skip to content

Memory leak: Ui files and direct approach

Wednesday, 21 November 2007 | Dominik Haumann


The KDE codebase often uses a forward declaration in the .h-file to speedup compilation. The code often looks like this:

// header file
namespace Ui { class MyWidget; }
class MyDialog : public KDialog {
  // ...
  private:
    Ui::MyWidget *ui;
};

The impl looks like this:

// source file
#include "mydialog.h"
#include "ui_mywidget.h"
MyDialog::MyDialog() : KDialog()
{
  QWidget *w = new QWidget(this);
  setMainWidget(w);
  ui = new Ui::MyWidget(); // allocation
  ui->setupUi(w);
  // ui->...
}

See the memory leak? You have to call »delete ui;« in the destructor if you use the »direct approach«. Searching in lxr.kde.org shows lots of results, and in some places this delete is missing indeed. Happy fixing :)


Update: The really correct fix is to guard the pointer with an auto_ptr or scoped_ptr. For further details read the comments below. Or use another approach to include your ui-file.

    • *If you do not want to delete it manually, you can for instance use a workaround like this:

// header file
namespace Ui { class MyWidget; }
class MyWidget;
class MyDialog : public KDialog {
  // ...
  private:
    Ui::MyWidget *ui;
};

Source file:

// source file
#include "mydialog.h"
#include "ui_mywidget.h"

class MyWidget : public QWidget, public Ui::MyWidget {
public:
    MyWidget( QWidget * parent = 0 ) : QWidget( parent )
    { setupUi(this); }
};

MyDialog::MyDialog() : KDialog()
{
  ui = new MyWidget(this);
  setMainWidget(ui);
  QWidget *w = new QWidget(this);
  setMainWidget(w);
  ui = new Ui::MyDialog(); // allocation
  ui->setupUi(w);
  // ui->...
}