사용자 도구

사이트 도구


kb:memoryleakdetection

Memory Leak Detection

메모리 누수를 해결하는 방법과 도구들…

CrtDumpMemoryLeaks

from http://www.codeproject.com/debug/consoleleak.asp

할당한 메모리를 삭제하지 않고 프로그램이 종료되었을 때…

33 CMainFrame::CMainFrame()
34 {
35     // TODO: 여기에 멤버 초기화 코드를 추가합니다.
36     int* shit = new int[100];
37 }

MFC를 사용하는 애플리케이션에서는 다음과 같은 에러 메시지를 출력한다.

즉 파일과 라인 번호가 나온다는 말이다. 그렇다면 MFC를 사용하지 않는 애플리케이션에서는 이것이 불가능한가? 그렇지 않다.

메모리 누수 추적하기

다음과 같은 파일을 만들자.

LeakWatcher.h
#ifndef IMWATCHINGYOULEAK
#define IMWATCHINGYOULEAK
 
#include <crtdbg.h>
 
#ifdef _DEBUG
#define THIS_FILE __FILE__
 
inline void* __cdecl operator new(size_t size, const char* filename, int line)
{
    return ::operator new(size, 1, filename, line);
}
 
inline void __cdecl operator delete(void* ptr, const char *filename, int line)
{
    ::operator delete(ptr, _NORMAL_BLOCK, filename, line);
}
 
#define DEBUG_NEW new(THIS_FILE, __LINE__)
#define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, THIS_FILE, __LINE__)
#define calloc(c, s) _calloc_dbg(c, s, _NORMAL_BLOCK, THIS_FILE, __LINE__)
#define realloc(p, s) _realloc_dbg(p, s, _NORMAL_BLOCK, THIS_FILE, __LINE__)
#define _expand(p, s) _expand_dbg(p, s, _NORMAL_BLOCK, THIS_FILE, __LINE__)
#define free(p) _free_dbg(p, _NORMAL_BLOCK)
#define _msize(p) _msize_dbg(p, _NORMAL_BLOCK)
 
#endif // _DEBUG
 
#endif // IMWATCHINGYOULEAK

모든 소스(.cpp) 파일의 마지막 #include 문 아래에다 다음과 같은 코드를 추가한다.

#include "LeakWatcher.h"
 
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

필요할 때 _CrtDumpMemoryLeaks() 함수를 호출한다. 예를 들어 프로그램이 종료되었을 때 보고 싶다면 메인 함수의 마지막 부분에다 추가하면 될 것이고, 일정 간격으로 호출하게 만들어도 상관없다.

위에서 한 일들이 하는 역할은 무엇인가?

MFC 에서 하는 일과 똑같은 일이다. 메모리를 할당할 때마다, 파일과 라인 넘버를 저장해두고, _CrtDumpMemoryLeaks() 함수를 호출할 때마다 그에 대한 정보를 출력하는 것이다. 사실 각각의 소스 파일마다 집어넣은 코드는 MFC의 애플리케이션 위자드가 각각의 소스 파일마다 생성하는 코드와 똑같은 코드다.

왜 그냥 _CRTDBG_MAP_ALLOC 을 사용하지 않는가?

#define _CRTDBG_MAP_ALLOC 은 malloc에 의해서 메모리 누수가 생긴 경우에는 파일과 라인을 보여주지만, new를 이용해 메모리 누수가 생긴 경우에는 crtdbg.h 파일에서 누수가 생겼다고 알려준다. (crtdbg.h 파일에 MS가 기본적으로 설정한 new 연산자가 존재하기 때문) 알다시피 이 파일에서 누수가 생겼다고 알려줘봤자 별로 쓸모가 없다.

문제점

  • new 연산자를 오버라이드해서 사용하는 애플리케이션에서는 잘 동작하지 않는다.
  • 헤더 파일에서 new 연산을 수행하는 경우, 잘 동작하지 않는다.

도구들

kb/memoryleakdetection.txt · 마지막으로 수정됨: 2014/11/08 16:59 (바깥 편집)