Qt memory deallocation - delete of an object with QList of object pointers attribute - Avoid memory leak

98 Views Asked by At

I have a C++ program (developed in Qt) with the GetVariablesRequest class. This class has the attribute getVariableData (QList of pointers of the GetVariableDataType class).

class GetVariablesRequest
{
public:
    GetVariablesRequest();
    ~GetVariablesRequest();

    QList<GetVariableDataType*> getVariableData;
}

class GetVariableDataType
{
public:
    GetVariableDataType();
    ~GetVariableDataType();

    int x;
};

I use the class as reported below.

....
GetVariablesRequest* request = new GetVariablesRequest();

GetVariableDataType* type1 = new GetVariableDataType();
GetVariableDataType* type2 = new GetVariableDataType();
GetVariableDataType* type3 = new GetVariableDataType();
GetVariableDataType* type4 = new GetVariableDataType();

request->getVariableData[0] = type1;
request->getVariableData[1] = type2;
request->getVariableData[2] = type3;
request->getVariableData[3] = type4;
...

If I call the delete of the "request" variable (as reported below), is also the memory of the objects type1, type2, type3 and type4 deallocated correctly? Or only the memory of the request variable is deallocated? Will I have a memory leak?

...
delete request;

I would avoid memory leak.

1

There are 1 best solutions below

0
Mauro On

I will try to summarize here the discussion we had in the comments that ultimately led to answering the question.

Container of pointers

A container of pointers (like QList<element_type*> or even std::vector<element_type*>) stores pointers and does not own or even care about the objects pointed to by the pointers themselves.

The destructor of a standard container takes care of clearing up the resources allocated by the container itself during its lifetime, nothing more.

Deleting the objects pointed to by the pointers inside the container is the responsibility of the calling code. This can be achieved by iterating on the container entries and by invoking the delete expression over each pointer. Since this is a common scenario for Qt developers, the library provides an helper method: qDeleteAll() [doc].

Notice that qDeleteAll() doesn't remove the items from the container; it merely calls delete on them.

The previous sentence means that the elements of the container should be removed by clearing the container. Of course, if you invoke qDeleteAll() in ~GetVariablesRequest, where you know the container will no longer be accessed before its deletion, you can avoid clearing the container.

Design issues

As other users have pointed out, it is not a good idea to store raw pointers in a container. If your application requirements are so that GetVariableDataType must be accessed through a pointer, it is better to use smart-pointers like std::shared_ptr or std::unique_ptr. The latter would be the proper one to use given that the container is taking ownership of the pointed to object.

Examples on Live Compiler