Как найти, где утечка памяти?

#c #visual-c #memory-leaks

#c #visual-c #утечки памяти

Вопрос:

Я добавил следующее в конец моего основного файла, и я получаю отчет об утечке памяти, но не создана точка останова, показывающая, где происходит утечка в моем коде, когда я запускаю его в режиме отладки. Я использую VS c 2010 Express. Есть ли что-то, что я делаю неправильно, или что-то не так с кодом, который я добавил. Я могу опубликовать больше кода, если это будет полезно.

 #ifdef _WIN32
if (_CrtDumpMemoryLeaks()) {
    cout << "Memory leaks!" << endl;
}
#endif

#ifdef _DEBUG
int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
flag |= _CRTDBG_LEAK_CHECK_DF; // Turn on leak-checking bit
_CrtSetDbgFlag(flag);
_CrtSetBreakAlloc(427);
#endif
  

Комментарии:

1. Если ваш код компилируется в Linux, попробуйте valgrind в Linux….

2. Попробуйте VLD — vld.codeplex.com

Ответ №1:

 int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
flag |= _CRTDBG_LEAK_CHECK_DF;
_CrtSetDbgFlag(flag);
  

Этого вполне достаточно, чтобы включить обнаружение утечек памяти. Не вызывайте _CrtSetDbgFlag напрямую.
Однако, чтобы получить строку исходного кода, где была вызвана утечка выделения, вам нужно сделать немного больше.

Добавляйте эти строки в начало каждого .cpp-файла, сразу после всех строк #include:

 #ifdef _DEBUG
#define new DEBUG_NEW
#endif
  

Для проекта MFC этого достаточно, заголовки MFC содержат DEBUG_NEW . Для проектов, отличных от MFC, создайте файл DebugNew.h:

 #pragma once

#include "crtdbg.h"

#ifdef _DEBUG
#define DEBUG_NEW   new( _NORMAL_BLOCK, __FILE__, __LINE__)
#else
#define DEBUG_NEW
#endif
  

Включите это в каждый cpp-файл. Отчет об утечках памяти теперь должен выглядеть следующим образом:

 Detected memory leaks!
Dumping objects ->
c:projectstestmain.cpp(20) : {181}     normal block at 0x005A80F8, 100 bytes long.
 Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 
Object dump complete.
  

Ответ №2:

http://msdn.microsoft.com/en-us/library/4wth1ha5.aspx

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

Насколько я знаю, функция _CrtSetBreakAlloc позволит отладчику прерваться, когда приложение попытается выделить местоположение, переданное в качестве аргумента.

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

 Dumping objects ->
{276} normal block at 0x007AC200, 4 bytes long.
 Data: <    > CD CD CD CD 
Object dump complete.
  

Тогда вызов функции был бы _CrtSetBreakAlloc(276);

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