PDA

View Full Version : Memory leaks with Valgrind on a simple code with QUiLoader



Sparhawk
6th April 2011, 18:17
Hi,

Maybe too much hours working, maybe I have been looking the code for too much time, maybe I don't understand exactly the documentation, or maybe there are no error, but I have some memory leaks with this code and I feel unable to find a solution. I'm trying to load from a ui file a QMainWindow.



#include <QApplication>
#include <QTranslator>
#include <QObject>
#include <QUiLoader>
#include <QFile>

int main(int argc, char *argv[])
{
QMainDlg *mainWin = 0;

QApplication app(argc, argv);

// Cargamos el archivo con las traducciones
QTranslator translator;
if (translator.load("qt_es", app.applicationDirPath()) == false) {
QMessageBox::warning(0, QString::fromUtf8(APP_NAME),
QObject::trUtf8("Ha sido imposible cargar el fichero con las traducciones."));
} else {
app.installTranslator(&translator);
}

QString fileName = QString("/home/david/tmp/main.qmaindlg.ui");
QUiLoader uiLoader;

if ( QFile::exists(fileName) ) {
QFile file (fileName);
file.open( QFile::ReadOnly );
QWidget *wid = uiLoader.load(&file, 0);
if ( wid != NULL ) {
wid->setAttribute(Qt::WA_DeleteOnClose);
wid->show();
}
file.close();
bool rc = app.exec();
return rc;
}
}


I simplify the main.qmaindlg.ui file to this:



<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QMainDlg</class>
<widget class="QMainWindow" name="QMainDlg">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>790</width>
<height>126</height>
</rect>
</property>
<property name="windowTitle">
<string>Presupuestos - Pinelo Talleres Gráficos</string>
</property>
<property name="windowIcon">
<iconset>
<normaloff>:/aplicacion/recursos/icono_app_peque.png</normaloff>:/aplicacion/recursos/icono_app_peque.png</iconset>
</property>
<widget class="QWidget" name="centralwidget"/>
</widget>
<connections/>
</ui>


I use the Qt47supp.txt provides on Nokia Labs... The output of Valgrind is attached. You can see a lot of "definitely lost". 6195

Is this normal? Something wrong with my code? I have no idea and I have several crashes on my applications, related with this, I think.

Thanks a lot.

high_flyer
8th April 2011, 10:07
I can't check at the moment to be 100% sure, but it makes sense to me that QUiLoader doe NOT delete widgets it created, since it would mean an instance of QUiLoader would have to be kept alive as long as the widgets it created are alive.
And since you are not deleting the widgets you created with QUiLoader, you have a leak.


QWidget *wid = uiLoader.load(&file, 0);

Try adding a clean up code for wid, or give it a parent, and see if the leaks are gone.

Sparhawk
8th April 2011, 10:55
Thanks for your answer. I know that QUiLoader does not delete widgets. It only create this. You have to assign a parent to the widget, or use

wid->setAttribute(Qt::WA_DeleteOnClose);
like I use on the code. I'm not sure if this attribute is enough to ensure that the widget will be deleted.
Anyway, I use QUiLoader on other places on my app, and I assign a parent to the widget recently created, and I get the same leaks.

Thanks!

high_flyer
8th April 2011, 12:07
Sorry, I was reading the code to fast, I didn't notice that line.
Hmm- did you check the Qt bug tracker, maybe its has been reported as a bug?

Sparhawk
8th April 2011, 12:40
Yes, I searched and found some bugs similar but not with QUiLoader. I asked here before open a new bug. But if you, or someone can test my code, and see no error on the code or in my "understanding" of QUiLoader, I will open the bug.

I have a similar problem using QtScript... But this one in a new post.

Thanks a lot again.

stampede
8th April 2011, 12:45
Change the line

QWidget *wid = uiLoader.load(&file, 0);
to

QWidget *wid = new QWidget();
and see if leaks are still reported.

Sparhawk
8th April 2011, 13:17
Hi,

If you see the documentation of QUiLoader, the load method says:

"Loads a form from the given device and creates a new widget with the given parentWidget to hold its contents."

So I understand that QUiLoader::load creates (make the "new") the widget.

Anyway I will test your suggestion.

Thanks a lot.

wysota
8th April 2011, 13:23
Anyway, I use QUiLoader on other places on my app, and I assign a parent to the widget recently created, and I get the same leaks
Please provide a minimal compilable example reproducing the problem. Make sure the "leaks" are indeed leaks and not false positives or leaks caused by 3rd party libs. As far as I know Qt doesn't leak memory. I went briefly through your valgrind report and most of the "definitely lost" reports are either false positives or possible leaks caused by external libs.

Sparhawk
8th April 2011, 13:31
The code I put on the original post is compilable (unless I've been wrong with cut&paste). I'm not sure that the leaks are false positive: I mean, I use the suppress rules provide by Qt developers on Nokia blogs...
I think it is not a Qt problem... but I can't explain the Valgrind output. Maybe is related with the library used to display QIcon? I don't know...

wysota
8th April 2011, 13:37
The code I put on the original post is compilable (unless I've been wrong with cut&paste)
But it's not minimal. You're using a translator and some pixmaps. Remove those and then compare valgrind report with the original one. If you want to test QUiLoader then test QUiLoader and not a bunch of other stuff.


I'm not sure that the leaks are false positive: I mean, I use the suppress rules provide by Qt developers on Nokia blogs...
I'm sure many of them are false positives - like all the ones related to image plugins.

stampede
8th April 2011, 13:43
If you see the documentation of QUiLoader, the load method says:

Yes, I know, I just want you to verify that this leak report is related to QUiLoader::load(). I don't have possibility to test on linux now, also try if this code will cause "leak":


#include <QtGui>

int main(int argc, char ** argv){
QApplication app(argc,argv);
QWidget * w = new QWidget();
w->setAttribute(Qt::WA_DeleteOnClose);
w->show();
return app.exec();
}

I just think that QUiLoader has nothing to do with the "leak" report, its more the Qt::WA_DeleteOnClose flag. Of course I may be wrong, but I've been using QUiLoader without problems.

Sparhawk
23rd April 2011, 18:50
I test the code that stampede writes with Valgrind. The ouput is attached 6283. There are some "definitely lost" entries. I think it can't be Qt... I'm not sure what to do now. Has anyone made the same test?

Thanks

SixDegrees
23rd April 2011, 19:42
Most of the leaks are emanating from X, which is known to have memory leaks. There's nothing you can do about those. The others seem to be related to system calls; these might be actual leaks, or they might be an artifact of the kernel's internal memory management that don't actually leak memory. Like the X leaks, there's nothing you can do about them.

If you run your program for an extended period of time and exercise all of it's functionality over and over again, and the amount of memory leaked stays relatively constant, I'd quit worrying about it. You'll pay a small, fixed cost per application startup until someone gets around to fixing them, if they ever do.

If memory use grows continuously over time, it might be worth a more detailed look.