Close() & WA_DeleteOnClose does not clean everything
-
I having some issues with memory and I could narrow it down to this toy example. The problem is that when I set WA_deleteonclose attribute on a qlabel and call close, it does not free all the memory it allocated. In this example in a for loop I create and close a large number of qlabel objects which have images in the form of attached qpixmap.
When deleteonclose and close() are used, according to valgrind there is a lost memory; whereas if I manually call delete, there is not...
Can anyone tell me what I am doing wrong?
Instructions for the code: You will need a test image to attach to QPixmap. Any image is fine.
main.cpp:
@
#include <QtGui>
#include "mybutton.h"int main(int argc, char *argv[])
{
QApplication q(argc, argv);
QWidget window;
window.resize(200,100);
window.show();
MyButton *mybutton = new MyButton(&window);
mybutton->show();
return q.exec();
}
@mybutton.h:
@
#ifndef MYBUTTON_H
#define MYBUTTON_H#include <QPushButton>
class MyButton : public QPushButton
{
Q_OBJECT
public:
MyButton(QWidget *parent = 0);public slots:
void run();
};#endif // MYBUTTON_H
@mybutton.cpp:
@
#include "mybutton.h"
#include <QtGui>
#include <iostream>using namespace std;
MyButton::MyButton(QWidget *parent) :
QPushButton(parent)
{
setText("start");
move(45,45);
connect(this,SIGNAL(clicked()),this,SLOT(run()));
}void MyButton::run() {
for(int i=0;i<1000;i++) { cout<<"i:"<<i<<endl; QPixmap pix("testImage.pgm"); QLabel *lab = new QLabel(); lab->setPixmap(pix); lab->setAttribute(Qt::WA_DeleteOnClose); lab->close(); //delete lab; }
}
@ -
I haven't checked about this myself, but could it just be that valgrind doesn't show the correct result because of the way the Qt::WA_DeleteOnClose works..
Anyways, unless its unavoidable, I personally don't think it is a good way to manage memory. I have worked on a document editor like MS-Word in Qt and not used the Qt::WA_DeleteOnClose anywhere in the >10000 lines of code. Use the QObject parent/child relationship and use Aggregation and a sound design to delete objects when they are no longer needed.
One could always depend on smart pointers (Reference counting), in cases where the work flow requires objects to be shared by multiple objects and could be deleted by an object other than the creator. In extremely large projects, this is quite useful in my view. "Qt Pointer Types":http://labs.qt.nokia.com/2009/08/25/count-with-me-how-many-smart-pointer-classes-does-qt-have/.
-
Qt::WA_DeleteOnClose eventually causes a call to deleteLater(). The objects are actually deleted once the event loop runs. Maybe some of the objects are stuck there.
Anyways, Qt::WA_DeleteOnClose should be used for parent less QObjects only (e.g. stand alone toplevel widgets like a QMainWindow or a QDialog based UI). Everything else is deleted by the parent-child object relationship.