2013-03-31 3 views
0

Есть карта, она отображает int на номер Test*.Удалить указатели с карты

Все указатели Test* выделены и назначены на карту позже. Тогда, я deleteing значения карты и установите их в null.

После этого оно проверяет действительность one, и оно должно быть null. Но, one не null.

#include <QString> 
#include <QMap> 
#include <QDebug> 

class Test { 
    QString name; 
public: 
    Test(const QString &name) : name(name) {} 
    QString getName() const { return name; } 
}; 

int main() { 
    QMap<int, Test*> map; 

    Test *one = new Test("one"); 
    Test *two = new Test("two"); 
    Test *three = new Test("three"); 

    map.insert(1, one); 
    map.insert(2, two); 
    map.insert(3, three); 

    for (auto itr = map.begin(); itr != map.end(); itr++) { 
     Test *x = *itr; 
     if (x) { 
      delete x; 
      x = 0; // ** Sets null to the pointer ** // 
     } 
    } 

    if (one) // ** Here one is not 0 ?! ** // 
     qDebug() << one->getName() << endl; // ** And then here crashes ** // 
} 

Я думаю, что я пропустил что-то, когда я deleteING их в петле.

Как это можно исправить?

Второй вопрос: правильно ли это deletes выделенные указатели?

ответ

4

В цикле переменная x является локальным указателем только внутри цикла. Когда вы установите это значение NULL, вы на самом деле не устанавливаете других указателей на NULL.

Что вы должны к тому, чтобы установить ссылку, возвращаемую разыменования итератора в NULL:

*itr = nullptr; 

Это заставит указатель на карте будет NULL, но другие указатели будут по-прежнему указывая на настоящее освобожденная область памяти.


Если у вас есть два указателя, это вид выглядит следующим образом:

 
+-----+ 
| one | ---\ 
+-----+  |  +---------------+ 
      >--> | Test instance | 
+-----+  |  +---------------+ 
| x | ---/ 
+-----+ 

Если вы установили один из указателей она выглядит следующим образом:

 
+-----+ 
| one | ---\ 
+-----+  |  +---------------+ 
      >--> | Test instance | 
+-----+   +---------------+ 
| x | 
+-----+ 

Переменная x - NULL, но переменная one все еще указывает на объект. И если объект был удален, то разыменование этого указателя вызывает неопределенное поведение.

+0

Спасибо, я обновил вопрос, как насчет моего второго вопроса. – deepmax

+1

Возможно, по второму вопросу вы спрашиваете, освобождена ли память, указанная этими указателями. Когда вы вызываете delete с помощью указателя, он освобождает выделенную память. Поэтому, когда вы пытаетесь получить к нему доступ, он вызывает «ошибку сегментации». Потому что переменная «одна» становится свисающим указателем. –

+0

@Atique: Да, спасибо, подозревая Qt, я пропустил эти простые вопросы о указателях. – deepmax

1

Самый простой способ удалить все будет:

qDeleteAll(map); 
Смежные вопросы