사용자 도구

사이트 도구


kb:memoryleakdetection

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

kb:memoryleakdetection [2014/11/08 16:59] (현재)
줄 1: 줄 1:
 +====== Memory Leak Detection ======
 + ​메모리 누수를 해결하는 방법과 도구들...
 +
 +
 +====== CrtDumpMemoryLeaks ======
 +from [[http://​www.codeproject.com/​debug/​consoleleak.asp]]
 +
 +할당한 메모리를 삭제하지 않고 프로그램이 종료되었을 때...
 +<​code>​
 +33 CMainFrame::​CMainFrame()
 +34 {
 +35     // TODO: 여기에 멤버 초기화 코드를 추가합니다.
 +36     int* shit = new int[100];
 +37 }
 +</​code>​
 +MFC를 사용하는 애플리케이션에서는 다음과 같은 에러 메시지를 출력한다.
 +
 +{{memoryleakdetection_memoryleak.gif}}
 +
 +즉 파일과 라인 번호가 나온다는 말이다. 그렇다면 MFC를 사용하지 않는 애플리케이션에서는 이것이 불가능한가?​ 그렇지 않다.
 + 
 +==== 메모리 누수 추적하기 ====
 +다음과 같은 파일을 만들자.
 +<file cpp 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
 +</​file>​
 +
 +모든 소스(.cpp) 파일의 **마지막 #include 문 아래에다** 다음과 같은 코드를 추가한다.
 +<code cpp>
 +#include "​LeakWatcher.h"​
 +
 +#ifdef _DEBUG
 +#define new DEBUG_NEW
 +#undef THIS_FILE
 +static char THIS_FILE[] = __FILE__;
 +#endif
 +</​code>​
 +
 +필요할 때 _CrtDumpMemoryLeaks() 함수를 호출한다. 예를 들어 프로그램이 종료되었을 때 보고 싶다면 메인 함수의 마지막 부분에다 추가하면 될 것이고, 일정 간격으로 호출하게 만들어도 상관없다.
 +
 +==== 위에서 한 일들이 하는 역할은 무엇인가?​ ====
 +MFC 에서 하는 일과 똑같은 일이다. 메모리를 할당할 때마다, 파일과 라인 넘버를 저장해두고,​ _CrtDumpMemoryLeaks() 함수를 호출할 때마다 그에 대한 정보를 출력하는 것이다. 사실 각각의 소스 파일마다 집어넣은 코드는 MFC의 애플리케이션 위자드가 각각의 소스 파일마다 생성하는 코드와 똑같은 코드다.
 +
 +==== 왜 그냥 _CRTDBG_MAP_ALLOC 을 사용하지 않는가? ====
 +<​nowiki>#​define _CRTDBG_MAP_ALLOC</​nowiki>​ 은 malloc에 의해서 메모리 누수가 생긴 경우에는 파일과 라인을 보여주지만,​ new를 이용해 메모리 누수가 생긴 경우에는 crtdbg.h 파일에서 누수가 생겼다고 알려준다. (crtdbg.h 파일에 MS가 기본적으로 설정한 new 연산자가 존재하기 때문) 알다시피 이 파일에서 누수가 생겼다고 알려줘봤자 별로 쓸모가 없다.
 +
 +==== 문제점 ====
 +  * new 연산자를 오버라이드해서 사용하는 애플리케이션에서는 잘 동작하지 않는다.
 +  * 헤더 파일에서 new 연산을 수행하는 경우, 잘 동작하지 않는다.
 +
 +
 +====== 도구들 ======
 +  * [[http://​www.codeproject.com/​useritems/​visualleakdetector.asp | Visual Leak Detector - Enhanced Memory Leak Detection for Visual C++]]
 +  * [[http://​www.codeproject.com/​tools/​leakfinder.asp | Memory(-Leak) and Exception Trace (CRT and COM Leaks)]]
 +  * [[http://​www.codeproject.com/​cpp/​MemLeakDetect.asp | Memory Leak Detection]]
 +  * [[http://​www.flipcode.com/​articles/​article_memoryleaks.shtml | How To Find Memory Leaks]]
 +  * [[http://​msdn.microsoft.com/​msdnmag/​issues/​07/​01/​ManagedLeaks/​Default.aspx?​loc=ko | MSDN Magazine > 관리 코드에서 메모리 누수 확인 및 방지]]
 +
 +----
 +  * see also [[MemoryManagement]]
  
kb/memoryleakdetection.txt · 마지막으로 수정됨: 2014/11/08 16:59 (바깥 편집)