메모리 누수를 해결하는 방법과 도구들…
from http://www.codeproject.com/debug/consoleleak.asp
할당한 메모리를 삭제하지 않고 프로그램이 종료되었을 때…
33 CMainFrame::CMainFrame() 34 { 35 // TODO: 여기에 멤버 초기화 코드를 추가합니다. 36 int* shit = new int[100]; 37 }
MFC를 사용하는 애플리케이션에서는 다음과 같은 에러 메시지를 출력한다.
즉 파일과 라인 번호가 나온다는 말이다. 그렇다면 MFC를 사용하지 않는 애플리케이션에서는 이것이 불가능한가? 그렇지 않다.
다음과 같은 파일을 만들자.
#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의 애플리케이션 위자드가 각각의 소스 파일마다 생성하는 코드와 똑같은 코드다.
#define _CRTDBG_MAP_ALLOC 은 malloc에 의해서 메모리 누수가 생긴 경우에는 파일과 라인을 보여주지만, new를 이용해 메모리 누수가 생긴 경우에는 crtdbg.h 파일에서 누수가 생겼다고 알려준다. (crtdbg.h 파일에 MS가 기본적으로 설정한 new 연산자가 존재하기 때문) 알다시피 이 파일에서 누수가 생겼다고 알려줘봤자 별로 쓸모가 없다.