управление памятью с ++ - PullRequest
1 голос
/ 17 августа 2011

Это хороший способ удалить карту длинных и объектов, созданных с помощью нового

// iterate over the map
for (std::map<unsigned long, Object*>::iterator it = objects.begin(), it_end = objects.end(); it != it_end; ++it)
{
    Object* temp = it->second;
    if(temp)
        delete temp;
}

// clear the map
objects.clear();

Ответы [ 6 ]

10 голосов
/ 17 августа 2011

Да. Используйте boost :: ptr_map

boost::ptr_map<std::string, BigObject>   data;

data.insert("Plop", new BigObject);

Когда данные выходят за пределы области, они удаляют все свои value члены.
Также для алгоритмов все члены возвращаются как ссылки на объект (не указатель), таким образом, гораздо проще использовать со стандартными алгоритмами, чем std :: map , где вам потребуется отменить ссылку memebrs перед использованием.

Можно задать вопрос, почему у вас есть карта указателя на int / long? Не будет ли проще просто сохранить значение на карте?

4 голосов
/ 17 августа 2011

Да, хотя лучшим решением было бы использование умных указателей вместо Object*, но это уже другая тема.

Вы можете сократить содержание для до

{
   delete it->second;
}

delete null определен и является noop.

2 голосов
/ 17 августа 2011

Это хорошее начало.

После удаления объекта вы должны либо удалить указатель с карты, либо установить его в NULL, чтобы избежать висячих указателей. Изменить: или, конечно, вы можете просто очистить карту, когда вы закончите, как показывает ваш пример.

Когда вы храните указатели в любом из стандартных контейнеров, всегда существует вероятность того, что исключение или какая-либо ошибка кода приведут к утечке памяти. В качестве альтернативы я бы предложил контейнеры для повышения указателя .

2 голосов
/ 17 августа 2011

Это прекрасный способ удаления.

Хотя вы можете значительно облегчить себе жизнь, используя умный указатель.

1 голос
/ 17 августа 2011

Я бы порекомендовал использовать умный указатель, например std::unique_ptr (это функция C ++ 0x, пока не все компиляторы ее поддерживают).Например:

std::map<unsigned long, std::unique_ptr<Object>> map;
// Do something with the map
map.clear(); // The objects are automatically deleted.

Вы также можете использовать std::shared_ptr (или boost::shared_ptr, если ваш компилятор не поддерживает интеллектуальные указатели C ++ 0x), что дает преимущество в том, что он будет работать, если ваша картаможет содержать один и тот же указатель более одного раза, и ваши объекты не будут уничтожены, если у кого-то еще есть указатель на них.

boost::ptr_map также варианты, хотя я считаю, что, как и при ручном подходе, не будет работать правильно, если карта содержит один и тот же указатель более одного раза.

1 голос
/ 17 августа 2011

Да.Независимо от того, что может считаться проблемой дизайна или архитектуры (например, использование более умных указателей), использование этого метода для очистки карты не является необоснованным.

Одно условие: карта objects должнане изменено уничтожением указателей Object *.Если это так, может быть лучше использовать что-то вроде этого:

// iterate over the map
typedef std::map<unsigned long, Object*>::iterator map_iter;
for (map_iter it = objects.begin();
    it != objects.end();
    /* blank */ )
{
    iter_map to_delete = it;
    ++it;
    Object* temp = to_delete->second;
    if(temp)
        delete temp;
    objects.delete(to_delete);
}
...