Deleting all values from a QMap
Asked Answered
G

2

14

I have a QMap consist of pointers to class objects, allocated using new. I need to delete all these pointers. What is the proper way of doing this with QMap ? I can do it this way:

QList<ClassName*> allVals = map.values();
for (QList<ClassName*>::iterator it = allVals.begin(), endIt = allVals.end(); it != endIt; ++it) {
    delete *it;
}

But is there a better way of doing the same ?

Gavriella answered 6/4, 2013 at 10:39 Comment(1)
Duplicate of https://mcmap.net/q/828094/-delete-pointers-from-a-map/…Karenkarena
W
31

The best way to do this is to use qDeleteAll(...):

qDeleteAll( map );  //  deletes all the values stored in "map"
map.clear();        //  removes all items from the map

qDeleteAll(...) can be used on all of Qt's containers. This way you don't need to worry about a loop nor worry about deleting items individually.

Welford answered 6/4, 2013 at 11:40 Comment(5)
I declare a QMap like this QMap<int, QString> list_items;. When I use qDeleteAll(list_items) then I got an error message is error: type 'const class QString' argument given to 'delete', expected pointer. Do you have an idea in this case?Jigsaw
@TanViet You can use qDeleteAll in case you store pointers in your map. You have this error because you store by value, and then trying to delete it as a pointer. Take a look here[link]qt-project.org/doc/qt-4.8/qtalgorithms.html#qDeleteAll I think list_items.clear() would be enough in your case.Keven
@Keven is correct. You only need to use qDeleteAll(…) when the map contains pointers. When a map is deleted or cleared the items within it will lose scope & be destroyed, but pointers will be left dangling and you would leak memory unless you delete them first. So the typical strategy is to use qDeleteAll(…) prior to clearing or deleting a map if the map contains pointers that must be deleted. Otherwise qDeleteAll(…) is not necessary.Welford
If your keys are also pointers, will qDeleteAll delete them?Wives
@Wives no, see the documentation: “Only the objects stored in each container will be deleted by this function; objects used as keys will not be deleted.”Welford
S
1

If both key and value are stored as pointers. You need to execute qDeleteAlltwice for keys and for values. Order doesn't matter. Simple example:

#include <QtCore/QCoreApplication>
#include <QDebug>
#include <QHash>

class MyKey
{
public:
    MyKey(int val)
    {
        m_val = val;
        qDebug() << "ClassKey()";
    }
    ~MyKey()
    {
        qDebug() << "~ClassKey() " << m_val;
    }
private:
    int m_val;
};

class MyValue
{
public:
    MyValue(int val)
    {
        m_val = val;
        qDebug() << "ClassValue()";
    }
    ~MyValue()
    {
        qDebug() << "~ClassValue() " << m_val;
    }
private:
    int m_val;
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QHash<MyKey *, MyValue *> hash;
    for (int i = 0; i < 10; ++i)
    {
        hash.insert(new MyKey(i), new MyValue(10 + i));
    }
    qDeleteAll(hash.keyBegin(), hash.keyEnd());
    qDeleteAll(hash.begin(), hash.end());
    hash.clear();
    return a.exec();
}
Sain answered 25/8, 2022 at 6:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.