DCRT ¶
Debug C Runtime 클래스를 이용하면 라이브러리가 알아서 동적할당되는 메모리를 역추적하여 누수되는 메모리를 가늠하는 것이 가능하다.
자기가 짠 프로그램으로 돌려보고 누수 여부를 판단하기에 좋을 것이다.
자기가 짠 프로그램으로 돌려보고 누수 여부를 판단하기에 좋을 것이다.
~cpp _crtDbgFlag
¶
_CRTDBG_ALLOC_MEM_DF | 디버그 할당 활성화. free store 상태 추적 |
_CRTDBG_DELAY_FREE_MEM_DF | 메모리를 delete에 의해 해지 되지 않도록함. 메모리 부족상황하에 발생하는 일을 알 수 잇음 |
_CRTDBG_CHECK_ALWAYS_DF | _CrtCheckMemory() 함수를 모든 new, delete 함수에 대해서 자동 호출 되도록 지정한다. 이 함수는 할당된 공간의 유효성을 지속적으로 체크한다. 즉 domainerror나 기타 메모리 access에 관한 부분을 검사한다. 대신 오버헤드가 상당하다. 그러나 그만큼 디버깅의 효율성을 높여줄 수 있다. |
_CRTDBG_CHECK_CRT_DF | 내부적으로 사용되는 메모리가 디버그작업을 하는 동안 추적된다. |
_CRTDBG_LEAK_CHECK_DF | 프로그램이 종료되는 시점에서 _CrtDumpMemoryLeaks()를 호출. 메모리 해제에 실패한 경우 그 정보를 얻을 수 있다. |
_CRTDBG_ALLOC_MEM_DF 는 기본적으로 on, 기타 플래그는 디폴트 off이므로 bitwise 연산자를 이용해서 적절하게 플래그를 설정해야한다.
~cpp int flas = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); flag |= _CRTDBG_LEAK_CHECK_DF; // 플래그 on flag &= !_CRTDBG_LEAK_CHECK_DF; // 플래그 off _CrtSetDbgFlag(flag);
Code ¶
~cpp //this define must occur before any headers are included. //반드시 include 전처리기의 앞부분에 선언되어야함. #define _CRTDBG_MAP_ALLOC #include <stdio.h> #include <stdlib.h> #include <string.h> #include <tchar.h> // include crtdbg.h after all other headers. // 전처리 문장이 끝난뒤에 include #include <crtdbg.h> int main(int argc, char *argv[]) { //turn on the full heap checking //DCRT의 오버헤드가 상당하기 때문에 기본옵션이 꺼져있다고 한다. 따라서 다음과 같이 옵션을 활성화 하는 작업이 필요 _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); //Allocate some more memory. TCHAR* pNew = new TCHAR[200]; TCHAR* pNew2 = new TCHAR[200]; TCHAR* pMemLeak = (TCHAR*)malloc (100); _tcscpy( pNew, _T("New'd memory...") ); _tcscpy( pNew2, _T("more New'd memory...") ); _tcscpy( pMemLeak, _T("Malloc'd memory...") ); return EXIT_SUCCESS; }
MFC에서는 기본적으로 로드하지만 콘솔에서는 사용자가 직접 지정을 해줘야 로드한다.
CRT 기타 함수 ¶
CRT의 기본 함수들의 출력은 디버그 메시지 윈도우이다. 이를 변경하기위해서는 _CrtSetReportMode()라는 함수를 이용해서 출력에대한 일반 목적지를 지정하고, _CrtSetReportFile()를 이용해서 특별한 스트림 목적지를 설정해야한다.
~cpp int _CrtSetReportMode(int reportType, int reportMode);
reportType
_CRT_WARN | 경고 메시지 예)memory leak |
_CRT_ERROR | 복구불가한 치명적 에러 |
_CRT_ASSERT | assertion 출력(assert() 출력이 아니다) |
crtdbg.h는 ASSERT, ASSERTE라는 메크로 함수를 생성한다. 둘의 차이점은 ASSERTE는 assertion 표현을 보고하고, 다른 것은 하지 않는 다는 것이다.
reportMode_CRTDBG_MODE_DEBUG | 디버그 윈도우 안에서 보게될 디버그 문자열에 출력을 전달 |
_CRTDBG_MODE_FILE | output stream |
_CRTDBG_MODE_WNDW | 메시지 박스 |
_CRTDBG_REPORT_MODE | 현재의 리포트 모드를 리턴한다. |
다중 목적지 지정은 flag 설정과 마찬가지로 | 연산자를 통해서 가능하다.
~cpp _HFILE _CrtSetReportFile(int reportType, _HFILE reportFile);
두번째 인수는 파일 스트림의 _HFILE 형식의 포인터이거나 다음의 식별자들 중의 하나이다.
_CRTDBG_FILE_STDERR | 표준 에러 스트림으로 전달 |
_CRTDBG_FILE_STDOUT | 표준 출력 스트림으로 전달 |
_CRTDBG_REPORT_FILE | 현재의 목적지를 리턴한다. |
output in debug console (vc++6) ¶
after ¶
대체로 클래스에서의 메모리 유출은 동적 멤버 변수들이 만들어졌을 때 해야하는 '삼의 법칙'을 지키지 않는데서 비롯되는 경우가 많다.