Загрузка...

суббота, 19 апреля 2008 г.

Утечка памяти в C++

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

Базовой операцией выделения памяти является оператор new, который может использоваться для создания массива динамической длины:

int size = 10;
int *array = new int[ size ];
// некоторый код
delete [ ] array;

Понятно, что к утечке может привести ситуация, когда перед вызовом оператора delete произошла безвозвратная передача управления (например, через оператор return). Поэтому настоятельно рекомендуется использовать контейнеры STL, в частности, vector. Они успешно справляются с такой ситуацией.

Однако, есть один ленивый программист, который предлагает использовать нестандартный подход для автоматического решения поставленного вопроса. Хотя сам подход совсем не для ленивых :)

Суть метода проста - выделение памяти не в хипе (она же куча), а в стэке. А как известно, стэк очищается при выходе из области видимости. Но как это реализовать? Для этого надо использовать функцию alloca() библиотеки времени выполнения C. А чтобы совсем все красиво работало, дополнительно надо создать шаблонный класс для работы с деструкторами сложных объектов и, наконец, один макрос, сокращающий длинную запись. Вот только непонятно, чем этот метод проще использования того же vector.

Но ведь главное не красота, а функциональность и скорость! Автор утверждает, что доступ к стэку осуществляется за O(1) против O(n) хипа. Это, видимо, и есть главное преимущество подхода.

Консерваторам лишь могу посоветовать ознакомиться со статьей, в которой расписан метод управления динамической памятью. Скачав исходники и использовав их в своих проектах, можно следить и гибко управлять сбором мусора (утечками). Читать статью полностью (осторожно, английский)...

Если не хочется заморачиваться на эту тему, лучший совет - использовать умные указатели.

Чтобы не упустить из виду новые статьи, подпишись на RSS. Это просто!

8 коммент.:

Автор комментирует...

> Автор утверждает, что доступ к стэку осуществляется за O(1) против O(n) хипа.

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

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

В моем коде никогда не бывает утечек памяти. Решить проблему утечки памяти очень легко. Достаточно добиться того, чтобы в вашем коде не было ни одного вызова delete.

Alno комментирует...

Техника, которую использует автор конечно интересна)))

Однако, мне кажется, что для такой задачи давно уже разработаны автоматические указатели.

Евгений комментирует...

Очень трудно представить как это будет выглядеть на практике, потому что, Вы сами написали, что стэк очищается при покидании области видимости. Мне кажется в этом случае не применяют динамическую память, а используют локальные переменные...

Сергей | codeBlogZ комментирует...

Евгений, честно говоря, я не понял твой комментарий ;)

Анонимный комментирует...

> А как известно, стэк очищается при выходе из области видимости. Но как это реализовать? Для этого надо использовать функцию alloca() библиотеки времени выполнения C.

Комментарий: Память выделенная alloca() отчищается ТОЛЬКО после завершения функции, а не при выходе из области видимости!

Сам недавно наткнулся на такие грабли, когда вызов аллоки происходит в цикле и, как результат, переполнение стэка :-(.

Сергей | codeBlogZ комментирует...

Интересно, спасибо за замечание :)

Анонимный комментирует...

Юзай Deleaker ( http://deleaker.ru ) и не парься!!

Анонимный комментирует...

Deleaker? Да, вещь хорошая. Раньше пробовал Valgrind, BoundCheck, как то глючно работают, а Deleaker - самое то.

Отправить комментарий | Feed



 
^

Powered by BloggerCreative Commons License