All posts by Dominik

Dominik is a PhD student at the Control Theory and Robotics Lab, TU Darmstadt, as part of the Research Training Group GKMM (GRK1362). My research focuses on state estimation in distributed systems. As hobby, I contribute to the KDE project and work on the Kate application and editor component.

Kate Meeting: Day 0

Finally it all begins: Anders and Joseph arrived at basysKom and we’ve started to discuss some things we want to do for KDE 4.1. Later, we are going to meet with the rest of the attendees in a restaurant to get to know each other. The official start of the meeting is tomorrow morning. If you are interested in contributing to Kate, just join #kate on irc.kde.org. I’m looking forward to the next two days :)

Memory Leak Continued

There was some confusion with regard to my last blog about leaking memory. Suppose the ui_mywidget.h files looks like this:

class Ui_Widget
{
public:
   QGridLayout *gridLayout;
   QGroupBox *groupBox;
   QGridLayout *gridLayout1;
   QListWidget *listWidget;
   QSpacerItem *spacerItem;
   QPushButton *pushButton;

   void setupUi(QWidget *Widget);
   void retranslateUi(QWidget *Widget);
};

Of course, those 6 QObject derived classes are deleted. But the sizeof(Ui_Widget) = 6 * sizeof(void*) = 24 bytes are not deleted. As Ui_Widget is not QObject derived those 24 bytes leak. Confirmed by valgrind.

In a comment to my last blog Paolo suggested to use auto_ptr or scoped_ptr, which is more elegant than an extra wrapper class :)

Memory leak: Ui files and direct approach

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->...
}