본문 바로가기

프로그래밍/기타

메모리누수 기능 체크



VS 의 메모리 누수 탐지기능을 이용한 방법이다.


사용방법은 매우 간단하다.


#define _CRTDBG_MAP_ALLOC

#include <stdlib.h>

#include <crtdbg.h>

// 헤더 부분에 선언


그리고 프로그램 초기부분에 아래와 같은 함수를 추가해 준다.


_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);





crtdbg.h 가 포함이 되면 malloc 이나 free와 같은 메모지할당 해제가 여기에 정의된 함수를 이용하여


메모리 추적을 할 수가 있다.


_CRTDBG_MAP_ALLOC 은 CRT 힙 함수의 버전을 해당 디버그 버전에 매핑하며,


생략하면 덤프표시가 덜 나오게 된다.


프로그램이 끝나는 부분에 _CrtDumpMemoryLeaks() 함수를 표기해야 종료시 덤프창을 볼 수 있으나,


종료지점이 여러가지인 경우, 각각 표기할 필요는 없다.


_CrtSetDbgFlag가 각 종료지점 마다 _CrtDumpMemoryLeaks() 을 자동으로 호출하기 때문이다.


기본적으로 메모리덤프는 디버그창에 출력을 하나,


_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG ); 를 추가할 경우


출력 위치를 출력 창으로 변경할 수 있다.



int sp* = new int; 

이런식으로 할당하고 해제를 안하게 된다면,


Detected memory leaks!

Dumping objects ->

{5} normal block at 0x0061F8B0, 4 bytes long.

 Data: <    > CD CD CD CD 

Object dump complete.

이와 같은 덤프창이 뜬다.


5는 메모리 할당번호인데, 해당 프로그램에서 5번째로 할당했다는 뜻이다.


그런데 반드시 코드상에서 new로 5번째 할당했다고는 볼 수 없다.


CRT 라이브러리나 MFC 라이브러리에서 할당할 수도 있기 때문이다.


normal block은 보통 메모리라는 뜻이며,


0x0061F8B0 는 메모리 위치(16진수)이며, 4byte는 블록크기이다.


그 다음은 블록 내 데이터(16진수) 이다.


사실 코드가 클 경우, 할당번호로 추적하기는 어렵기 때문에


대부분 메모리를 할당한 파일이름과 라인을 체크하여 많이 사용한다.


#if _DEBUG

#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)

#define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)

#endif


이런식으로 new를 재정의한다면,


Detected memory leaks!

Dumping objects ->

d:\main.cpp(191) : {5} normal block at 0x02EAA2A8, 4 bytes long.

 Data: <    > CD CD CD CD 

Object dump complete.


다음과 같이 파일과 라인 표시가 된다.





여기까지가 고전적인 VS 메모리체크 방식이고,


좀 더 자세한 덤프기능을 활용하려면 VLD 기능을 쓰라고 하고 싶다.


http://honestgame.tistory.com/101