Search code examples
c++qtmemory-managementqlistqbytearray

I cannot delete an item in a QList <QByteArray*>


I am trying to delete (free memory) of all QByteArrays in QList of pointers to the QByteArrays. Here's my code:

in my .h file

        QList<QByteArray*> GroupWord;                                   //declare the QList

in my .cpp file

        quint8 k = GroupWord.length();                                  //get the last Index
        QByteArray& ref = *GroupWord.at(k - 1);                         //get the last Index
        qDebug() << "Length before deletion: " << GroupWord.length();   //print out the length before deletion
        qDebug() << "Before deletion: " << *GroupWord.at(k - 1);        //print out before del
        GroupWord.at(k - 1)->~QByteArray();                             //destroy the entry
        qDebug() << "Length after deletion: " << GroupWord.length();   //print out the length after deletion
        *GroupWord.at(k - 1)->append('l');                              //append to the 'assumed' deleted entry
        qDeleteAll(GroupWord);                                          //qDeleteAll the QList
        qDebug() << "After deletion 1: " << ref;                        //print out the ref to entry
        qDebug() << "After deletion 2: " << *GroupWord.at(k - 1);       //print out entry
        qDebug() << "After deletion 3: " << GroupWord.at(k - 1);        //print out the pointer
        GroupWord.clear();
        qDebug() << "After deletion 4: " << ref;                        //the memory is still there after ~QByteArray() and qDeleteAll() =(((((

Here's how I know the QByteArray in question has not been deleted:

The length of the QList still stays the same after ~QArrayByte();

enter image description here

I don't really know what's going on here :(

I know that I shouldn't declare variable like this, and just pass it around into voids; and when the QList gets out of scope, it will be automatically deleted. But, I just want to test something out :(

Thank you guys very much in advance,

And have a nice day, :X


Solution

  • GroupWord.at(k - 1)->~QByteArray(); destroys the object but doesn't deallocate memory of its dynamic storage. You never removed the pointer from QList. Storing objects themselves instead of pointers would.. actually QList would store pointers and begins to manage the objects if they are QObject (QList is too clever for its own good , being designed to be idiot-proof). Which would lead to UB if you would try to call destructor.

    QList "knows" its length only due to calls to its methods, it tracks it. The destruction you did is outside of its scope: GroupWord.at(k - 1) is a call of QList member, ->~QByteArray(); is a call of QByteArray method in context of objects returned by pointer from at.

    You almost NEVER, EVER call destructor explicitly. Rare case when it's actually needed are some things like allocating objects with placement new, for them you cannot call delete as the storage doesn't belong to them.

    QList uses a form of placement new inside of it, but that changes from version to version of Qt. What matters is that it's not a container with continuous storage for its elements. if you store pointers in QList<QByteArray*>, you have to remove them manually and delete pointed object if that's appropriate: beware of double deletion or deletion of something that wasn't created by new. If you use QList<QByteArray>, QList manages that automatically, but it would always make a copy.