광고 수익은 기아대책 서울본부에 기부합니다.

2011.11.24 10:04 윈도우/스터디


Visual Studio 출력 창에 메모리 릭이 표시 된다. 예제 프로그램으로 간단히 정리 한다.
MFC 프로젝트를 이용하는 경우, 소스 위쪽에

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

위 코드를 추가하여 메모리 릭 위치를 추적 할 수 있다. 콘솔 프로그램인 경우 아래와 같이 한다.

1) 예제 프로그램 - 콘솔 응용 프로그램

// MemoryLeakTest.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//

#include "stdafx.h"

// 콘솔 프로젝트에서 메모리릭 정보가 출력 창에 출력될 수 있도록 추가
#include <crtdbg.h>


int _tmain(int argc, _TCHAR* argv[])
{
 // 콘솔 프로젝트에서 메모리릭 정보가 출력 창에 출력될 수 있도록 추가
 _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

 int *nData = new int;

 return 0;
}

출력 값은 아래와 같다.

'MemoryLeakTest.exe': 'F:\Data\Study\MemoryLeakTest\Debug\MemoryLeakTest.exe' 로드, 기호가 로드되었습니다.
'MemoryLeakTest.exe': 'C:\Windows\SysWOW64\ntdll.dll' 로드
'MemoryLeakTest.exe': 'C:\Windows\SysWOW64\kernel32.dll' 로드
'MemoryLeakTest.exe': 'C:\Windows\SysWOW64\KernelBase.dll' 로드
'MemoryLeakTest.exe': 'C:\Windows\winsxs\x86_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.30729.6161_none_2a4f639a55563668\msvcr90d.dll' 로드, 기호가 로드되었습니다.
'MemoryLeakTest.exe': 'C:\Windows\SysWOW64\apphelp.dll' 로드
'MemoryLeakTest.exe': 'C:\Windows\SysWOW64\apphelp.dll' 언로드
Detected memory leaks!
Dumping objects ->
{116} normal block at 0x00698680, 4 bytes long.
 Data: <    > CD CD CD CD
Object dump complete.
'[2120] MemoryLeakTest.exe: 네이티브' 프로그램이 종료되었습니다(코드: 0 (0x0)).


{116} normal block at 0x00698680, 4 bytes long.
여기서 {116}은 메모리 생성 순서이다. 116번째 메모리 생성시 브레이크 포인트를 건다.

// MemoryLeakTest.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//

#include "stdafx.h"

// 콘솔 프로젝트에서 메모리릭 정보가 출력 창에 출력될 수 있도록 추가
#include <crtdbg.h>


int _tmain(int argc, _TCHAR* argv[])
{
 _CrtSetBreakAlloc(116); // 116 번째 메모리 생성시 프레이크 걸리도록 추가

 // 콘솔 프로젝트에서 메모리릭 정보가 출력 창에 출력될 수 있도록 추가
 _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

 int *nData = new int;

 return 0;
}

실행 시키면 아래와 같이 중단점이 트리거 된다.


중단을 누르고 호출 스택을 보면 아래와 같다.

호출 스택에서 해당 위치로 가면 아래와 같이 메모리릭 발생 지점을 가리킨다.

하지만 프로그램이 크고 여러 모듈들이 비순서 적으로 로딩 되면 메번 실행시마다 생성되는 메모리 순서가 바뀌게 됩니다.

// MemoryLeakTest.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//

#include "stdafx.h"

// 참고 : http://support.microsoft.com/kb/601929/ko

// 콘솔 프로젝트에서 메모리릭 정보가 출력 창에 출력될 수 있도록 추가
// 디버그 빌드 메모리 함수를 이용하여야 릭 표시시 파일이름이 표시된다.
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>

int _tmain(int argc, _TCHAR *argv[])
{
 //_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
 int *nData = (int*) malloc(16);

 _CrtDumpMemoryLeaks( );
 return 0;
}

위와 같이 Define 을 추가하면 아래와 같이 해당 위치가 표시된다.

'MemoryLeakTest.exe': 'F:\Data\Study\MemoryLeakTest\Debug\MemoryLeakTest.exe' 로드, 기호가 로드되었습니다.
'MemoryLeakTest.exe': 'C:\Windows\SysWOW64\ntdll.dll' 로드
'MemoryLeakTest.exe': 'C:\Windows\SysWOW64\kernel32.dll' 로드
'MemoryLeakTest.exe': 'C:\Windows\SysWOW64\KernelBase.dll' 로드
'MemoryLeakTest.exe': 'C:\Windows\winsxs\x86_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.30729.6161_none_2a4f639a55563668\msvcr90d.dll' 로드, 기호가 로드되었습니다.
'MemoryLeakTest.exe': 'C:\Windows\SysWOW64\apphelp.dll' 로드
'MemoryLeakTest.exe': 'C:\Windows\SysWOW64\apphelp.dll' 언로드
Detected memory leaks!
Dumping objects ->
f:\data\study\memoryleaktest\memoryleaktest.cpp(16) : {116} normal block at 0x00418680, 16 bytes long.
 Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.
'[3892] MemoryLeakTest.exe: 네이티브' 프로그램이 종료되었습니다(코드: 0 (0x0)).

더블 클릭 하여 해당 위치로 찾아간다.

'윈도우 > 스터디' 카테고리의 다른 글

DLL (Dynamic Link Library) 정리  (0) 2012.01.16
Media Transfer Protocol (MTP)  (0) 2011.12.15
PostThreadMessage로 SendThreadMessage 구현하기  (0) 2011.11.28
_stprintf_s  (0) 2011.11.28
Visual Studio C++ 메모리 릭  (2) 2011.11.24
posted by Town One townone

댓글을 달아 주세요

  1. Programmerj 2012.01.20 17:02  Addr  Edit/Del  Reply

    유용한 팁 잘 읽었습니다.^^
    요즘 디버깅에 관련해서 관심이 많은 혹시 추천해 주실만한 책있을까요?
    내일 부터 설 연휴네요~! 즐거운 명절 되시고! 새해 복 많이 받으세요^^

  2. 오맹 2012.01.30 15:06  Addr  Edit/Del  Reply

    감사합니다.
    1월 20 날에 제가 수술을 하는 바람에 ...
    디버깅은 로그 잘 남기고 map 파일과 미니 덤프 이용 하시고 지뢰 잘 놓으면 될 듯 싶네요. ^^
    저도 디버깅 책은 보지 않았구요. 인터넷에서 찾아보면서 하는 실정이라. 책추천은 힘들겠네요. 죄송해요.