У меня есть приложение, которое было создано с использованием .net Framework 3.5. Однако теперь мне нужно изменить это, чтобы использовать 2.0 Framework, так как он должен распространяться на компьютер с Windows 2000. Я также прочитал документацию по MSDN об обнаружении утечек русалки и также начал использовать Visual Leak Detector. У меня есть сомнения по поводу ...
Я хочу обнаружить утечки памяти моей программы на C ++ в Windows. Я также прочитал документацию на MSDN об обнаружении утечек слияния и также начал использовать визуальный детектор утечек.
У меня есть сомнения по поводу сообщения об утечках. Я ожидаю имя файла с номером строки, но мне всегда сообщается текст ниже. Он содержит все компоненты описания утечки (тип блока, адрес памяти, данные и т. Д.) кроме имени файла и номера строки.
Если это настоящая утечка? Если да, знаете ли вы, почему файл / строка не сообщается? В то же время я смотрю также этот URL
Спасибо
Detected memory leaks! Dumping objects -> {4723} normal block at 0x04AFB5B8, 8 bytes long. Data: 2C 3F 00 00 28 3F 00 00 {1476} normal block at 0x04AC3B58, 12 bytes long. Data: 00 CD CD CD EB 01 75 4C CA 3D 0B 00 Object dump complete.
Вы должны использовать Valgrind , он очень мощный и правильно объясняет, где находятся утечки в ваша программа. Ваша программа может нуждаться в компиляции с помощью gcc, хотя ...
Я исследовал несколько различных способов отслеживания утечек памяти. У всех есть свои преимущества, но есть и недостатки.
Чтобы понять их преимущества и недостатки, мы должны понять различные механизмы и требования:
Как перехватываются new, delete, malloc и free? Некоторые инструменты используют #define для переопределения new, delete, malloc и free, но это зависит от правильного порядка включаемых файлов и может вызвать проблемы, если класс содержит, например, метод под названием free (как в Qt). Препроцессор также переопределит этот метод, что может привести к ошибкам компиляции или неразрешенным внешним факторам.
Другой способ - отменить глобальные операторы new и delete. Это гораздо более чистое решение, но оно не работает, если у вас есть сторонняя библиотека, которая помещает новую в библиотеку, но удаляет ее в заголовке (или наоборот).
Как определяется источник звонка. Если new, delete, ... перехватываются с помощью #define, часто символы препроцессора __ FILE __
и __ LINE __
используются для определения источника утечки. Однако, если в вашем коде есть «общие» функции, например, CreateString (), то большинство утечек будет сообщаться в этих общих функциях, что на самом деле вам не поможет.
Альтернативой является получение стека вызовов во время выполнения. Это довольно легко сделать с помощью функции Windows StackWalk, но, по моему опыту, это очень медленно.Гораздо более быстрая альтернатива - напрямую получить базовый указатель и полагаться на указатели-кадры стека (вы должны скомпилировать с / Oy-, чтобы получить указатели-кадры стека). Вы можете получить указатель фрейма (базы) следующим образом: _asm mov DWORD PTR [FramePtr], ebp
. Затем просто выполните цикл и в цикле получите указатель инструкции из ((ADDR *) FramePtr) [1];
и следующий указатель кадра из FramePtr = ((ADDR *) FramePtr) [0 ];
Как сообщить об утечках в нужный момент. В моем случае я хочу, чтобы об утечках сообщалось в конце приложения, но для этого вам понадобится механизм отчетов об утечках в конце приложения. Это означает, что если вы хотите сообщать о своих утечках самостоятельно, вам нужно полагаться на глобальные переменные, которые уничтожаются в конце вашего приложения (и сообщать об утечках в деструкторе глобальной переменной). Для приложений серверного типа вас, вероятно, больше интересует разница в использовании памяти между двумя точками времени.
А теперь различные системы утечек:
C RunTime: сообщает об утечках в конце, но не имеет достойного способа сообщить о стеках вызовов. Его метод перехвата вызовов new, delete, ... может вызвать проблемы в сочетании со сторонними библиотеками (такими как Qt, Boost, ...)
Внешние утилиты Microsoft (например, GFlags, UMDH ,, ...): они, кажется, могут регистрировать различия только между двумя моментами времени. Однако стек вызовов кажется намного лучше, хотя утилита GFlags может устанавливать флаги в ОС, которые могут вызвать серьезное замедление работы вашего приложения.
Визуальный детектор утечки.Кажется, все утечки обнаруживаются правильно, но в моем случае это не работает, так как у меня есть сторонняя DLL, которая просто прерывает процесс на своем DllUnload (похоже, это проблема Windows 7).
Мой личный фаворит (и я уверен, что люди со мной не согласятся) - написать свой собственный менеджер памяти. Перехват можно легко выполнить с помощью глобальных операторов new и delete (с возможными проблемами, упомянутыми выше), и вы можете получить стек вызовов, как описано выше. Эта альтернатива также зависит от возможности иметь код, который выполняется в самый последний момент в вашем приложении.
Выбирая альтернативу, я обнаружил, что следующие аспекты очень важны для моей ситуации:
Надеюсь, это поможет.
Я получил это после отладки большого количества файлов заголовков.
Вот что нужно сделать, чтобы включить номер файла/строки в выводе
#define _CRTDBG_MAP_ALLOC
#define _CRTDBG_MAP_ALLOC_NEW
Rational Purify доступен как платный плагин для VC++ и является очень хорошим детектором утечек (и других проблем). Раньше я часто использовал его в Solaris, и он был очень простым в использовании и понятным. Я также слышал хорошие отзывы от других людей о версии для использования с Visual Studio, но я никогда не пробовал это.
FWIW, я подозреваю, что Purify послужил источником вдохновения для Valgrind, о котором уже упоминалось.
Вы выполнили компиляцию с включенной отладочной информацией и убедитесь, что файл pdb доступен для течеискателя? Без этой информации он не сможет предоставить номера строк.
Если номера распределения (в фигурных скобках) всегда одинаковы, это может помочь. По сути, в нем описано, как заставить VC++ генерировать точку останова при попытке выделения памяти с указанным номером.
Это выходные данные собственной CRT отладки Visual Studio, а не выходные данные Visual Leak Detector. Во-первых, убедитесь, что вы используете текущую версию в Codeplex и что у вас есть #included vld.h в вашем проекте. Вы получите гораздо более информативный вывод.