2015-01-27 2 views
0

В старой версии Visual C++ отладчик смог обнаружить утечки памяти. Например, следующий кодОбнаружение утечек памяти в VC 2012

#define _CRTDBG_MAP_ALLOC 
#include <stdlib.h> 
#include <crtdbg.h> 

#include "stdafx.h" 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    char *memleak= new char[100]; 
    memleak[0]='a'; 
    return 0; 
} 

должно привести к сообщению, что есть memleak из 100bytes. Что-то вроде этого: (См. MSDN)

Обнаруженные утечки памяти! Сбрасывающие объекты -> {18} нормальный блок при 0x00780E80, 100 байт в длину. данные: <> CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD Сброс объекта.

Но я не могу «заставить» это сообщение. Есть ли что-то, что мне нужно включить? или мне нужно установить некоторые дополнительные функции? Я использую Studio Prof. 2012 Update 4.

ответ

2

Ответ от @Vinzenz несколько на месте, но я постараюсь дать все подробности. У вас в основном есть два варианта: либо сделать отладочную среду выполнения дампом утечки, когда программа выйдет (это можно сделать, включив отчет об утечке памяти, вызвав _CrtSetDbgFlag с флаговым значением, которое имеет бит бит _CRTDBG_LEAK_CHECK_DF), или как упомянутый звонок _CrtDumpMemoryLeaks() сбросьте утечки в произвольной точке выполнения. Поскольку ваш пример не делает ни одной из этих вещей, вы ничего не получаете.

Что нужно знать о _CrtDumpMemoryLeaks(), что он будет выгружать распределения кучи, которые не были освобождены в момент, когда он вызывается, поэтому любые интеллектуальные указатели (и все другие объекты, которые выделяют кучную память внутри), которые не были уничтожены, будут сбрасывается в этот момент. Вот почему использование флага отчета несколько лучше, так как оно запускается после завершения выполнения программы, поэтому все объекты, которые должны быть уничтожены, уничтожаются.

Что касается DBG_NEW, он дает вам дополнительную информацию о линии, показывающую линию, вызвавшую утечку. Без него вы получите вывод, как в примере в вопросе, с ним вы получите номер строки, вызвавшей это (см. Пример ниже).

#define _CRTDBG_MAP_ALLOC 
#include <stdlib.h> 
#include <crtdbg.h> 

/* 

Without the DBG_NEW you get something like, no line info 

Detected memory leaks! 
Dumping objects -> 
{74} normal block at 0x00000000005D6520, 100 bytes long. 
Data: <    > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 
Object dump complete 

With it you get 

Detected memory leaks! 
Dumping objects -> 
strcattest.cpp(36) : {74} normal block at 0x00000000002C6520, 100 bytes long. 
Data: <    > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 
Object dump complete. 

*/ 

#ifdef _DEBUG 
#ifndef DBG_NEW 
#define DBG_NEW new (_NORMAL_BLOCK , __FILE__ , __LINE__) 
#define new DBG_NEW 
#endif 
#endif // _DEBUG 

int main(int argc, char* argv[]) 
{ 
    // Enable automatic memory leak reporting at the end of the program, the next 3 lines can be skipped if _CrtDumpMemoryLeaks() is called somewhere 
    int current_flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); 
    current_flags |= _CRTDBG_LEAK_CHECK_DF; 
    _CrtSetDbgFlag(current_flags); 
    char *memleak= new char[100]; 
    _CrtDumpMemoryLeaks(); // Trigger dumping the leaks at this point 
    return 0; 
} 
+0

Спасибо за подробный ответ ... Теперь я задаюсь вопросом, почему он работал со старой версии: -/ – nobs

+0

@nobs что ты имеешь в виду старую версию? –

+0

Мы использовали VS 2005 с тем же кодом Там у нас были сообщения. не знаю, что изменилось, но я не собираюсь снова выкапывать старую версию – nobs

1

Вы прочитали эту статью MSDN? Как вы используете new для выделения памяти, вы должны добавить следующую строку:

#ifdef _DEBUG 
    #ifndef DBG_NEW  
     #define DBG_NEW new (_NORMAL_BLOCK , __FILE__ , __LINE__) 
     #define new DBG_NEW 
    #endif 
#endif // _DEBUG 

Вы также можете позвонить _CrtDumpMemoryLeaks() «заставить» выход всех обнаруженных утечек памяти в любой точке программы. Однако я предпочитаю делать это на выходных точках моих приложений.

Смежные вопросы