Congratulations to our 2022 Qt Champions!

Will this memory leak?

  • NOTE: It's just an illustrative class, the real part is the struct to hold information and the return of it.

    #include <QObject>
    #include <QMap>
    #include <QDebug>
    class MyClass : public QObject {
    	struct Information {
    		QString description;
    		MyClass *instance;
    	} information;
    	explicit MyClass(QObject *parent = 0);
    	void sayHi();
    	QMap<QString, MyClass::Information> container;
    MyClass::MyClass(QObject *parent) : QObject(parent)
    	information.description = QString("It does something really interesting");
    	information.instance = this;
    	qDebug() << "hi';
     // it's going to be on the header to have global access in other methods of the c lass...
    MyClass *myclass = new MyClass(this);
    container.insert("MyClass", myclass->information);
    // ... later on
    MyClass *ret = container.value("MyClass").instance->sayHi();
    qDebug() << container.value("MyClass").description;

    I want to know if it's going to memory leak in any moment.

    I was using Intel Inspector but it's not working properly on Windows 10 and VS2015 anymore.

  • Yes it will leak and it's also not valid so it won't compile.

    Let me show you the areas I saw as an issue on casual inspection (I may have missed stuff):

    MyClass *myclass = new MyClass(this);
    // You allocate a MyClass object but you store only the Information struct in the map.  
    // This causes you to lose your myclass pointer and therefore can never clean it up with delete.  
    // It is leaked the second myclass goes out of scope.
    container.insert("MyClass", myclass->information);
    // the following line is not valid.  
    // You are trying to get a pointer to a MyClass object from a function that has no return type.  
    // sayHi() does not return a pointer to MyClass.
    MyClass *ret = container.value("MyClass").instance->sayHi();
    qDebug() << container.value("MyClass").description;

    Now to fix this you need to modify your map to be like:

    class SomeContainer
       // you don't want your map inside MyClass.  
       //At least not without it being static and available to any instance of MyClass.
       QMap<QString, MyClass *> container;

    And you can access it with:

    MyClass *obj = container.value("MyClass");
    // or ...

    And finally when you're done with everything, clean it all up:

       foreach (MyClass *obj, container)
          delete obj;

  • Lifetime Qt Champion

    @Defohin For classes derived from QObject: if you create an instance and pass a parent to the constructor that instance will be deleted as soon as parent is deleted. You can find this information in Qt documentation.

  • Thank you guys, helped a lot.

Log in to reply