13

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 ?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Littlebitter
  • 671
  • 3
  • 10
  • 19
  • 1
    Duplicate of http://stackoverflow.com/questions/15727958/delete-pointers-from-a-map/15730555#15730555 –  Apr 06 '13 at 13:16

2 Answers2

29

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.

Cutterpillow
  • 1,717
  • 13
  • 32
  • I declare a QMap like this `QMap 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? – Tan Viet Sep 09 '13 at 03:38
  • 4
    @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]http://qt-project.org/doc/qt-4.8/qtalgorithms.html#qDeleteAll I think list_items.clear() would be enough in your case. – miks131 Sep 12 '13 at 12:57
  • @miks131 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. – Cutterpillow Sep 17 '13 at 04:57
  • If your keys are also pointers, will `qDeleteAll` delete them? – Kvass Oct 14 '14 at 09:09
  • @Kvass 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.”](http://qt-project.org/doc/qt-5/qtalgorithms.html#qDeleteAll) – Cutterpillow Oct 15 '14 at 00:50
0

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();
}