2011-01-18 3 views
3

В некоторых классах у меня есть статическая std :: map с указателями внутри. Мой вопрос: если мне нужно удалить в конце программы или эта память автоматически освободится. Меня беспокоит, правильно ли удалены указатели, хранящиеся внутри, через наши деструкторы при удалении std :: map.Нужно ли удалить статическую std :: map?

Спасибо.

ответ

6

Если карта содержит указатели, которые были выделены с new (или new[], или malloc), то каждый указатель необходим соответствующий delete (или delete[] или free).

Деструктор карты не знает, что делать с лысой стрелкой. Рассмотрите возможность использования smart pointer, который имеет соответствующую семантику перемещения, например boost smart pointer, или если у вас есть очень новый компилятор, один из C++0x smart pointers. Однако не используют действующий стандарт std::auto_ptr, внутри контейнеров STL. See this thread for why.

Edit:

Как Билли ONeal отметил, boost::ptr_map также предназначен именно для этой цели.

+1

+1 - но w.r.t. auto_ptr Я бы использовал язык сильнее, чем «избегать», учитывая, что контейнеры auto_ptrs не должны компилироваться. (И auto_ptr отлично справляется везде). Также рассмотрите 'boost :: ptr_map'. –

+0

Спасибо за помощь. Я думаю, мне нужно двигаться, чтобы повысить 1.45 – Killrazor

0

Если у вас есть карта указателей, тогда ответ «нет», ваши деструкторы не будут вызываться, но «да», память будет освобождена в конце выполнения процесса. Вся память, выделенная процессом, всегда освобождается операционной системой, когда процесс завершается (даже если он сбой), но деструкторы могут не вызываться.

+0

Опять же, не всегда верно, но верно для большинства платформ. –

1

Память «автоматически освобождается», в том смысле, что вся память процесса освобождена, но деструкторы объектов, на которые указывает, не будут вызываться. Это может привести к утечке ресурсов, если вы используете RAII.

+0

Не всегда верно (хотя это верно для большинства платформ) –

1

std::map никогда не звонит delete на его членов. Предполагая, что вы работаете с относительно новой операционной системой, ОС вернет память, занятую членами при завершении процесса, но деструкторы не будут работать.

-1

Как и в любом случае класса хранения, в котором хранятся указатели: вы несете ответственность за освобождение памяти, на которую указывают. Класс хранения отвечает только за очистку собственных ресурсов. Опираясь на восстановление памяти ОС при завершении процесса, это плохая практика.

+0

«Класс хранения» разрешено делать практически все. Теперь стандартные контейнеры ничего не «удаляют», но вполне возможно иметь контейнер, который будет уничтожать его собственные члены. Например, boost :: ptr_map/boost :: ptr_vector –

+0

@Billy Согласитесь. Я использовал слишком широкий термин (класс хранения), но я думал о контейнерах STL. –

+0

@Bojan: 'boost :: ptr_vector' является контейнером STL, но он, безусловно, уничтожает его содержимое при его уничтожении. (О, и я не спустил вниз) –

2

Если я правильно понимаю ситуацию, вы не удаляете ее. Но вам, вероятно, нужно удалить объекты, на которые указывает карта. Вероятно, было бы действительно хорошей идеей использовать интеллектуальный указатель, такой как Boost shared_ptr на вашей карте вместо собственных указателей. Затем объекты будут очищены автоматически.

Редактировать: Использование Boost ptr_map может быть еще лучшей идеей.

0

Память «утечка» - это то, где память непреднамеренно не удаляется в течение определенного периода времени и заканчивается сокращением по мере продолжения процесса. Если это процесс, который выполняется в течение очень длительного периода времени, например сервер, который редко перезапускается, это может быть серьезной проблемой.

Детекторы утечки памяти будут извлекать любую память, которая выделяется и не удаляется вызовом программирования, поэтому valgrind и т. Д. Сообщают об этом как утечку.

Это также проверяет ваш код на программы, такие как valgrind, и, следовательно, чем меньше «мешает», тем легче будет выявлять настоящие утечки. Поэтому мой совет заключается не в том, чтобы позволить системе очистить память, или синглтоны и т. Д. Для вас, когда вы выделили указатель с новым (или malloc или new []).

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

+0

Вы предполагаете, что базовая платформа поддерживает концепцию «процесса», что не всегда верно. –

Смежные вопросы