Native Code에서 Memory Leak을 잡는 방법-1
일하는 곳에서 Memory Leak이 발생하는거 같다고 퇴근 딱 5분 남기고 말해주셨다.
오늘 다른 팀에 Binary Release를 하기위해 코드를 수정하였으나,
지금 말하는 곳은 쩐혀~~~ 다른 서버이기에 확인이 필요했다.
그러고 보니 VS에서 Memory Leak을 확인하는 여러 방법을 이번기회에 정리나 해야겠다.
항상 위기는 기회가 된다고 하지 않았는가~~ 캬캬캬캬캬
VS Debugger를 이용하는 방법
MSDN에 나와있는 것처럼 가장 쉬운 방법은 VS의 API를 이용하는 것이다.
다음의 함수를 프로그램이 종료하는 시점에 넣으면, Output 창에 그 결과가 나온다.
- _CrtDumpMemoryLeaks();
그런데 다음과 같은 경우에는 문제가 발생할 수도 있다.
- class MyClass
{
public:
MyClass(void)
{
_data = new char[100];
}
~MyClass(void)
{
delete[] _data;
}- private:
char* _data;
}; - MyClass _instance;
- int main(int argc, char* argv[])
{
_CrtDumpMemoryLeaks();
return 0;
}
다음과 같은 경우는 전역에서 Class를 선언하였기 때문에
main이 시작하기 전에 heap 영역에 할당되고, main이 종료한 이후에 heap에서 제거가 된다.
그러나 _CrtDumpMemoryLeaks()는 main함수가 종료직전에 메모리영역을 검사하기 때문에 다음과 같이 Memory leak으로 결정난다.
Detected memory leaks!
Dumping objects ->
c:\program files\microsoft visual studio 8\vc\include\crtdbg.h(1150) : {50} normal block at 0x003A2F50, 100 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.
The program '[3868] MemoryLeakTest.exe: Native' has exited with code 0 (0x0).
이러한 경우를 대비하여 main 함수의 시작 부분에 다음 부분을 입력하면 이러한 문제를 해결할 수 있단다.
실제로 잘 된다 ^^;;;
- _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
이렇게 작성된 코드의 예는 다음과 같다
- #define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h> - #include <iostream>
using namespace std; - class MyClass
{
public:
MyClass(void)
{
_data = new char[100];
}
~MyClass(void)
{
delete[] _data;
}- private:
char* _data;
}; - MyClass _instance;
- int main(int argc, char* argv[])
{
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); - char* a = new char[100];
return 0;
}
참고로 Memory Leak이 발생하지 않으면 아무런 메세지도 뜨지 않는듯~~
지금의 예제를 보면 찐하게 한 곳에 일부러 하나 넣어놨다!!
그럼 Output 창에서는 결과가 다음과 같이 나온다.
- Detected memory leaks!
Dumping objects ->
c:\program files\microsoft visual studio 8\vc\include\crtdbg.h(1150) : {51} normal block at 0x003A2FF0, 100 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.
중요한 부분은 뒤에 나오는 {51}이 코드의 라인이 아니라는 것이다.!!!
정확히는 잘 모르겠지만 Object Simbol의 위치가 아닐까 생각중 ㅡㅡ;;;
_CrtSetBreakAlloc(51); 의 함수를 이용하여 main program에서 돌리면 그 위치를 Call Stack에서 찾을 수 있다.
더 좋은 방법이 있을 것 같지만, 이것만으로도 나에게는 아주 나이쑤하다.
혹 좋은 방법 알고 계신 분은 좀 알려주세용~~~
이번 내용과 관련된 Link는 다음과 같다.
- MSDN의 표준화된 딱딱한 내용: http://msdn2.microsoft.com/ko-kr/library/x98tx3cf(VS.80).aspx
- VS에서 어떻게 Macro를 이용하여 처리하는지 설명한 내용: http://smilk.egloos.com/130469
- 조금은 다른 내용이지만 그래도 알아두면 피가되고 살이되는 것으로 STL을 써야하는 이유: http://www.debuglab.com/knowledge/autoptr.html
Bound Checker 및 다른 Tool을 사용하여 Memory Leak을 사용하는 방법은
내일 일찍 출근을 해야하는 관계로 다음번에 써야겠다~~
그럼 고양이도 잘자고 나도 잘자야징~~
History
Last edited on 07/20/2007 07:09 by again4you
Comments (1)
저 숫자는 메모리가 할당된 순서를 의미합니다. 위의 예에서는 "51번째로 할당된 메모리"가 회수되지 않았다는 의미입니다. ^^
01/06/2010 21:26