Как найти утечку памяти в коде / проекте C ++? - PullRequest
152 голосов
/ 07 июня 2011

Я программист C ++ на платформе Windows. Я использую Visual Studio 2008.

Я обычно заканчиваю в коде утечками памяти.

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

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

  1. Я хочу знать, как программист может обнаружить утечки памяти.
  2. Существует ли какой-либо стандарт или процедура, которой следует следовать, чтобы убедиться в отсутствии утечки памяти в программе?

Ответы [ 17 ]

3 голосов
/ 21 июля 2018

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

Также, чтобы найти утечку в конкретной функции, используйте exit (0) в конце функции, а затем запустите ее с Valgrind

`$` valgrind ./your_CPP_program 
3 голосов
/ 07 апреля 2015

MTuner - это бесплатный мультиплатформенный инструмент для профилирования памяти, обнаружения и анализа утечек, поддерживающий компиляторы MSVC, GCC и Clang.Особенности включают в себя:

  • история использования памяти на временной шкале и блоки оперативной памяти
  • мощная фильтрация операций с памятью на основе кучи, тега памяти, диапазона времени и т. Д.
  • SDK для ручного инструментария с полным исходным кодом
  • поддержка непрерывной интеграции с использованием командной строки
  • дерево стека вызовов и навигация по карте дерева
  • и многое другое.

Пользователи могут профилировать любое программное обеспечение с таргетингом на платформы с помощью кросс-компиляторов GCC или Clang.MTuner поставляется со встроенной поддержкой платформ Windows, PlayStation 4 и PlayStation 3.

3 голосов
/ 08 февраля 2015

AddressSanitizer (ASan) - это быстрый детектор ошибок памяти. Он находит ошибки переполнения use-after-free и {heap, stack, global} -buffer в программах на C / C ++. Находит:

  • Использовать после освобождения (разыменование висящего указателя)
  • Переполнение буфера динамической памяти
  • Переполнение буфера в стеке
  • Глобальное переполнение буфера
  • Использовать после возврата
  • Ошибки порядка инициализации

Этот инструмент очень быстрый. Среднее замедление инструментальной программы составляет ~ 2x.

3 голосов
/ 07 июня 2011

В Windows вы можете использовать CRT debug heap .

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

Да, не используйте ручное управление памятью (если вы когда-либо вызываете delete или delete[] вручную, то вы делаете это неправильно). Используйте RAII и умные указатели, ограничьте выделение кучи абсолютным минимумом (в большинстве случаев автоматических переменных будет достаточно).

3 голосов
/ 07 июня 2011

Отвечая на вторую часть вашего вопроса,

Существует ли какой-либо стандарт или процедура, которой необходимо следовать, чтобы убедиться в отсутствии утечки памяти в программе.

Да, есть.И это одно из ключевых отличий между C и C ++.

В C ++ вам никогда не следует вызывать new или delete в вашем пользовательском коде. RAII - очень распространенный метод, который в значительной степени решает проблему управления ресурсами.Каждый ресурс в вашей программе (ресурс - это все, что необходимо получить, а затем освободить: дескрипторы файлов, сетевые сокеты, соединения с базой данных, а также обычное распределение памяти, а в некоторых случаях - пары вызовов API (BeginX () / EndX (), LockY (), UnlockY ()) должны быть заключены в класс, где:

  • конструктор получает ресурс (путем вызова newесли ресурс является памятной записью)
  • деструктор высвобождает ресурс,
  • копирование и назначение либо запрещаются (делая конструктор копирования и операторы назначения частными),или реализованы для правильной работы (например, путем клонирования базового ресурса)

Этот класс затем создается локально, в стеке или как член класса, а не Вызов new и сохранение указателя.

Вам часто не нужно определять эти классы самостоятельно. Стандартные контейнеры библиотеки также ведут себя таким образом, поэтомуЛюбой объект, сохраненный в std::vector, освобождается после уничтожения вектора.Опять же, не храните указатель в контейнере (который потребует you для вызова new и delete), а скорее сам объект (который дает вам памятьуправление бесплатно ).Аналогичным образом, классы интеллектуальных указателей могут использоваться для простого переноса объектов, которые просто должны быть выделены с помощью new, и управления их временем жизни.

Это означает, что когда объект выходит из области видимости, он автоматически уничтожается,и его ресурс освобожден и очищен.

Если вы будете делать это последовательно по всему коду, у вас просто не будет утечек памяти.Все, что могло получить, привязано к деструктору, который гарантированно будет вызван, когда элемент управления выйдет из области, в которой был объявлен объект.

0 голосов
/ 20 февраля 2018

Ни "new", ни "delete" никогда не должны использоваться в коде приложения. Вместо этого создайте новый тип, который использует идиому «менеджер / работник», в которой класс менеджера выделяет и освобождает память и перенаправляет все другие операции в рабочий объект.

К сожалению, это больше работы, чем должно быть, потому что в C ++ нет перегрузки «оператора». Еще больше работы при наличии полиморфизма.

Но это того стоит, потому что вам больше не нужно беспокоиться об утечках памяти, а значит, вам даже не нужно их искать.

0 голосов
/ 05 июля 2017

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

...