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 {
    	Q_OBJECT
    
    public:
    	struct Information {
    		QString description;
    		MyClass *instance;
    	} information;
    
    	explicit MyClass(QObject *parent = 0);
    
    	void sayHi();
    
    private:
    	QMap<QString, MyClass::Information> container;
    };
    
    MyClass::MyClass(QObject *parent) : QObject(parent)
    {
    	information.description = QString("It does something really interesting");
    	information.instance = this;
    }
    
    MyClass::sayHi()
    {
    	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");
    obj->sayHi();
    
    // or ...
    container.value("MyClass")->sayHi();
    

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

    SomeContainer::~SomeContainer()
    {
       foreach (MyClass *obj, container)
          delete obj;
       container.clear();
    }
    

  • Moderators

    @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
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.