C/C++/프로그래밍 일반

알수없는 위치에 메모리릭이 발생하는 경우 검출법(vs2008기준)

Midach 2010. 4. 20. 03:45


다음과 같은 구문을 활용해 메모리 릭을 검출하는 경우(혹시 아래와 같은 구문을 처음 보신다면 메모리릭검출을 검색해서 관련부분을 살펴보고 오세요.)

_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

// 출력창으로 정보를 출력시킨다.
_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_DEBUG  );
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG  );
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_DEBUG  );

#define DEBUG_NORMALBLOCK new ( _NORMAL_BLOCK, __FILE__, __LINE__ )
#ifdef new
#undef new
#endif
#define new DEBUG_NORMALBLOCK


이런 케이스나
c:\test\test.cpp(9) : {228} normal block at 0x00666458, 4 bytes long.
 Data: <    > CD CD CD CD

이런 케이스로 메모리릭이 났다는 것을 알려준다.
{81253} normal block at 0x03BB0AD0, 16 bytes long.
 Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD

첫번째의 경우 파일명, 라인까지 친절하게 알려주기 때문에 메모리릭을 잡는데 어려움이 없지만
두번째의 경우 파일명과 라인이 없어 다소 당황스러울 수도 있다.(당연히 나올거라 예상했을거에요...)
하지만 이를 해결하기 위한 기타 여러가지 정보들이 있다.

다시 두번째 케이스를 보면,
{81253} normal block at 0x03BB0AD0, 16 bytes long.
 Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD

여기서 81253는 몇번째로 할당했는가를 나타낸다. 그리고 0x03BB0AD0 주소에서 릭이 발생했다는 것을 알 수 있다. 여기서 normal block은 new 또는 malloc중 하나로 동적할당 했다는 얘기고 총 16바이트가 릭이 발생했단 얘기다. 우리는 여기서 81253과 0x03BB0AD0 두가지 정보를 가지고 브레이크 포인트를 걸 예정이다.


첫번째 방법

main함수의 최상단에 다음과 같은 구문을 삽입
_crtBreakAlloc = 81253;

그리고 디버깅을 해보면, 해당지점에 브레이크포인트가 걸린다. 콜스택으로 따라가면 어디에서 릭이 발생했는지 알 수 있다.


두번째 방법

일단 F11로 디버깅을 시작한다.
ALT+F9를 눌러서 중단점 창을 연 후, 새로만들기>새데이터중단점에서 주소부분에 저 주소(0x03BB0AD0)를 입력하고, 적당한 바이트(위의 경우는 16)를 기입하고 확인
F5로 계속 진행하여 그 부분을 찾아낸다.