Как избежать утечек памяти - PullRequest
4 голосов
/ 22 марта 2011

Как мы можем использовать перегруженный оператор для предотвращения утечек памяти в C ++?

Любой полный пример ..

С уважением,

П

Ответы [ 4 ]

11 голосов
/ 22 марта 2011

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

Это может показаться парадоксальным, но правда в том, что ручное управление памятью подвержено ошибкам, лучше использовать автоматическое (илибиблиотека) technics.

В C ++ для каждого создаваемого вами объекта должно быть четкое владение.То есть вы должны быть в состоянии определить время жизни объекта, возможно, в зависимости от некоторых других.

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

Многого использования new можно избежать, используя контейнеры STL (например, std::vector<T>) вместо того, чтобы переходить в собственные ситуации.

Второй шаг - экономно использовать new и всегда передавать память одному владельцу сразу после ее выделения.К таким владельцам относятся:

  • std::unique_ptr (C ++ 0x) или boost::scoped_ptr, в крайнем случае std::auto_ptr.
  • boost::ptr_vector и вся коллекция Boost.Pointer Container library

Один владелец легко отследить, и поскольку время жизни объекта привязано к его владельцу, следовательно, время жизни объекта также легко отследить.

Третий шаг - деликатный, введение совместного владения.Это действительно усложняет все рассуждения о времени жизни объекта и создает риск циклов ссылок, которые фактически означают утечки памяти.Они требуются в некоторых ситуациях, но лучше избегать их, когда это возможно.

  • std::shared_ptr (C ++ 0x) или эквивалентный (std::tr1::shared_ptr, boost::shared_ptr)
  • std::weak_ptr (C ++ 0x) или эквивалентный

Последний используется для "разрыва" циклов.Однако может быстро стать трудно понять, где ввести weak_ptr, даже с графиком отношений.

РЕДАКТИРОВАТЬ:

Как отметил Тобиас, этоидиома известна как инициализация ресурсов (RAII), название которой неловко.Появляется новый термин: Scoped Bound Resources Management (SBRM), чтобы описать его подмножество -> связывание ресурсов с областью действия.

2 голосов
/ 22 марта 2011

Большинство людей рекомендуют использовать Boost или STL, но в некоторых случаях это невозможно (при разработке операционной системы, встроенных системах с ограниченными ресурсами и т. Д.). В этом случае убедитесь, что вы используете стек всякий раз, когда это возможно, и что вы используете new только внутри конструктора класса и delete внутри его дескриптора. Для двойной проверки есть несколько инструментов, которые помогут вам обнаружить утечки памяти, например valgrind.

2 голосов
/ 22 марта 2011

Просто добавьте немного общности к ответу Матея:

Всякий раз, когда вы используете ресурс, который необходимо освободить (память, сетевые подключения, файловые дескрипторы, дескрипторы окон, ...), используйте Инициализация ресурсов при инициализации (RAII) .

Одним из проявлений этой идиомы являются упомянутые выше std :: unique_ptr и boost :: scoped_ptr. Если у вас нет контейнера RAII для необходимого ресурса - создайте его. Это всегда стоит того.

1 голос
/ 22 марта 2011

Если вы хотите избежать утечек памяти, не катите свое собственное решение, используйте boost.shared_ptr .Если вы действительно хотите сделать это вручную, поместите код очистки в деструктор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...