1

So I have this method:

void SomeClass::SomeMethod() {
   QString information;
   QListWidgetItem *dataline = new QListWidgetItem();

   information = "stuff & more stuff";

   dataline->setText(information);
   dataline->setFont(QFont("Monospace"));
   dataline->setStuff(moreStuff::things);

   //! listData is a pointer to QListWidget object.
   ui.listData->insertItem(ui.listData.count(), dataline);
} //! Boom, memory leak!

In Qt docs it says something like this:

If you need to insert a new item into the list at a particular position, then it should be constructed without a parent widget. The insertItem() function should then be used to place it within the list. The list widget will take ownership of the item.

But VLD (Visual Leak Detector) detects memory leak every time I call that method.

1) Is VLD actually right about this, and there is a memory leak?

2) Is there another way of solving this? (I tried not to heap-allocate the dataline object, and pass the address of it to the insertItem method, but it seems that is not working.

EDIT: This is the class that holds the ui object:

#include "ui_Validator.h"

class Validator: public QMainWindow {
        Q_OBJECT
    public:
        Validator(QWidget *parent = 0);
        ~Validator();
    public slots:
        void stuff1();
        void stuff2();
        void stuff3();
        void stuff4(const QString &data);
        void stuff5(const Rats &data);
    signals:
        void startGeneratingSignal(Cat param);
        void stopGeneratingSignal(Dog param);
        void initStuff();
        void configStuff(Rats param);
        void stopThreadIOloop();
    private:
        Ui::Validator ui; //! This object is from Qt-generated ui_Validator.h.
        SomeThreadObj *objActivity;
        QThread *objActivity;
        SomeInterface interface;
    };

And the destructor from cpp file:

Validator::~Validator() {
    //! EDIT: It's ok, when this destructor is called, it means that all the application is closed, so there is no need for explicit cleanup, the OS will take care of that.
    ui.listData->clear();
    emit killIOloop();
    qDebug() << "~Validator";
}

So, like you can see, the ui object is constructed first time when the program starts (the main window), and goes out of scope when the destructor is called (when I exit the application) (for some reasons I intentionally don't delete objActivity and objActivity).

mariusmmg2
  • 713
  • 18
  • 37
  • Are you sure, that it's memory leak? Memory will be freed only when `ui.listData` will be destroyed. – ForEveR Aug 27 '15 at 07:47
  • 1
    Doesn't look like a leak to me (based on code shown). See if you can somehow (some annotation comment maybe) tell VLD that this pointer will be stored elsewhere. If there is no such way, then I would consider VLD unsuitable to be used with Qt apps in general, because there will be a lot of cases where you `new` an object, then pass it to another object which takes ownership of it, just like in this code. – hyde Aug 27 '15 at 07:47
  • @ForEveR This is the output of VLD: `---------- Block 980 at 0x06315F28: 24 bytes ---------- Leak Hash: 0x6A3FD59D, Count: 1, Total 24 bytes Call Stack (TID 6756): 0x52E8C260 (File and line number not available): MSVCR120D.dll!operator new c:\users\user\documents\visual studio 2013\projects\myapp\myappagain\file.cpp (284): app.exe!Class::MyLeakingMethod+ 0xB bytes` I'm not actually sure if VLD is right about this, that's why I'm asking. – mariusmmg2 Aug 27 '15 at 07:51
  • @MariusMG have no expirience with VLD, but I think, that `listData` will be destroyed only when `ui` will be destroyed, so, at the end of program actually. You may try to call `clear` on `listData` before ending of program. Or just write simple example, that will test, that `listData` is freed correctly. – ForEveR Aug 27 '15 at 07:55
  • Similar question, unfortunately with no solution: http://stackoverflow.com/questions/18443808/how-to-fix-memory-leak-while-inheriting-from-qobject – hyde Aug 27 '15 at 07:56
  • Can you add more code? With no information about `ui` and its lifecycle, it's hard to make a good answer. – Armaghast Aug 27 '15 at 08:21
  • @Armaghast I edited the question. – mariusmmg2 Aug 27 '15 at 09:39
  • I haven't used directly `listdata`, but I can see 2 possible reasons: - `Validator`'s instance isn't destroyed (does `"~Validator"`appears when you execute the program? Where is `Validator` instanciated?), - or clearing the listData manually break the `parent/child` relationship. Remove the `ui.listData->clear();` line, and tell us what happens. – Armaghast Aug 27 '15 at 11:19
  • Yes, `Validator`'s destructor is called. I also remove the `ui.listData->clear();` line from `Validator`'s destructor, with no change. The `Validator` object is instanciated in the main function. I just create a simple test class, trying to reproduce the problem, but there I don't have this problem... It must be something that I'm missing here – mariusmmg2 Aug 27 '15 at 11:34
  • mm.. According to the doc, `ui.listData->clear();` should destroy all its items. Calling it shouldn't be necessary anyway, as `Ui::Validator::~Ui::Validator` should be the one to do it. – Armaghast Aug 27 '15 at 11:35

1 Answers1

0

I have written a simple example with VLD and the code below:

test1::test1(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    QString information;
    QListWidgetItem *dataline = new QListWidgetItem();

    information = "stuff & more stuff";

    //Dataline dataline = new Dataline();
    dataline->setText("test");
    dataline->setFont(QFont("Monospace"));


    //! listData is a pointer to QListWidget object.
    ui.listData->insertItem(ui.listData->count(), dataline);
}

test1::~test1()
{

}

After the MainWindow is closed, QListModel Destructor is called and deletes all items of the ListWidget in a clear Method.

Output of VLD:

No memory leaks detected.
Visual Leak Detector is now exiting.

If you call the clear Method of the ListWidget explicit: Same Output.

Matthias
  • 463
  • 1
  • 7
  • 12