- 일반 콘솔에서 (MFC에서는 필요없음) 메모리 릭 출력하는 방법
-
추가해야 할 헤더
#include <stdlib.h>
#include <crtdbg.h>
- 메모리 릭 정보를 출력하고자 하는 라인에 추가할 함수나 매크로
1) 종료할 때 Dump를 미리 지시하는 매크로 (시작시 호출)
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
2) 명시적으로 메모리 릭 정보의 출력을 지시하는 함수 (종료시 호출)
_CrtDumpMemoryLeaks();
- 다음 그림처럼 출력된 메모리 릭 정보에서 할당한 라인의 정보가 나오지 않을 경우
- malloc의 경우 (2가지 방법)
프로젝트 설정의 전처리기에_CRTDBG_MAP_ALLOC 을 추가해준다.
MSDN에서는
#define _CRTDBG_MAP_ALLOC 을 1번에서 추가한 헤더위에 정의하면 된다고 하였지만 실제로는 되지 않았다.
- 다음 코드를 추가한다.
#if _DEBUG
#define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
#endif
- new의 경우
- 다음 코드를 추가한다.
#if _DEBUG
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endifmalloc의 경우와 비슷하게
_CRTDBG_MAP_ALLOC_NEW를 추가하면 crtdbg.h의 인라인 operator new가 불리게 되어 항상 crtdbg.h의 operator new에서 할당받은 것으로 나오므로 쓸모가 없어진다.
- 2번과 같은 문제를 할당된 순서(위 그림에서 {106}, {104})를 통해 Break를 거는 방법
- 최대한 빨리 _crtBreakAlloc 에 값을 설정한다.
(/MD 옵션으로 컴파일 했을 경우 {,,msvcr71d.dll}_crtBreakAllocdp에 값을 설정한다)
_crtBreakAlloc = 104; // 104번째 동적 할당 되었을 경우 break됨 - _CrtSetBreakAlloc(104); 으로 설정해도 된다.
- 상황에 따라 할당 순서가 달라지는 경우도 많이 생기기 때문에 엉뚱한 곳을 가리킬 수 있으니 사용할 때 주의해야 한다.
위 글을 읽어보는 것도 귀찮다면 다음 두가지만 추가한다.
- 할당 함수를 사용하기 전에 다음 코드 추가
#include <stdlib.h>
#include <crtdbg.h>
// 해제가 되지 않은 메모리의 할당 위치를 알기 위해 파일과 라인넘버를 입력하는 작업
#if _DEBUG
#define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
#if defined(__cplusplus)
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif
#endif
- 프로그램 시작 부분에 다음 코드 추가
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); // 정상 종료시 해제되지 않은 메모리 정보 출력한다
// _CrtSetBreakAlloc(104); // 104 번째 할당 시 Break가 걸린다
다음은 예제로 사용한 소스와 실행 결과이다.
Detected memory leaks!
Dumping objects ->
c:\documents and settings\digicaps\my documents\visual studio 2005\projects\temptestcode\temptestcode\temptestcode.cpp(29) : {106} normal block at 0x003A9F40, 13 bytes long.
Data: <Memory Leak! > 4D 65 6D 6F 72 79 20 4C 65 61 6B 21 00
c:\documents and settings\digicaps\my documents\visual studio 2005\projects\temptestcode\temptestcode\temptestcode.cpp(24) : {104} normal block at 0x003A9EF0, 13 bytes long.
Data: <Memory Leak! > 4D 65 6D 6F 72 79 20 4C 65 61 6B 21 00
Object dump complete.
'[3428] TempTestCode.exe: 네이티브' 프로그램이 0 (0x0) 코드에서 끝났습니다.