메모리 누수(Memory Leak)는 프로그램이 동적으로 할당한 메모리를 더 이상 사용하지 않음에도 해제하지 않아, 가용 메모리가 점점 줄어드는 현상을 말한다.
게임 클라이언트 같은 장시간 실행되는 애플리케이션에서는 특히 치명적일 수 있기 때문에, 반드시 신경 써줘야 하는 부분이다.
new를 통해 메모리를 동적할당하면, 힙(heap) 영역에 메모리를 할당받게 된다.
이 할당받은 메모리의 사용이 끝나면, 반드시 delete를 통해 메모리를 해제해줘야, 메모리 누수가 발생하지 않는다.
메모리 누수 디버깅
먼저, 메모리 누수를 발생시켜 보자.
다음과 같이, new를 통해 동적으로 메모리를 할당한 후, delete 없이 프로그램이 종료됐다.
#include <iostream>
int main()
{
int* Arr = new int[10];
}
그럼 사용자는 이 프로그램에서 메모리 누수가 발생했는지 어떻게 확인할 수 있을까?
마이크로소프트 문서인 msdn에 CRT 라이브러리로 메모리 누수 찾는 방법이 나와있다.
이 방법대로 프로그램의 메모리 누수를 찾아보자.
먼저, 메모리 누수 디버깅을 위해선 다음 구문을 추가해줘야 한다.
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
그리고, main 함수 다음 줄에 메모리 누수를 디버깅하는 구문을 추가한다.
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
이제 다음과 같이 작성한 코드를 실행한다.
#include <iostream>
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
int main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
int* Arr = new int[10];
}
프로그램이 종료된 후에 Output 로그를 보면, 다음과 같이 "Detected memory leaks!" 라고 하는 문장을 통해, 메모리 누수가 발견되었다는 로그를 발견할 수 있다.
- Detected memory leaks: 메모리 누수가 발견되었다!
- {79}: 해당 메모리 누수의 에러 코드 (때마다 바뀔 수 있음)
- 40 bytes long: 해당 메모리 누수에서 발생한 누수된 메모리의 크기

메모리 누수가 되고 있다는 사실을 알았는데, 이게 어느 위치에서 발생하는지를 아직 모르겠다.
하지만, 로그에서는 메모리 누수가 발생한 에러 코드도 포함하여 로그로 찍어준다.
위 예시에서는 {79}의 에러 코드를 통해 메모리 누수가 발생한 코드 위치를 찾을 수 있다.
해당 코드를 main함수에 넣어주면, 해당 에러 코드가 발생하면 오류를 일으킨다.
_CrtSetBreakAlloc(79);
에러가 발생하면, 해당 호출 스택을 확인한다.
호출 스택을 쭉 보다 보면, 오류가 발생한 파일과 오류가 발생한 줄에서 시작되었다는 것을 확인할 수 있다.

다른 방법
모든 메모리 누수를 이렇게 해결해야 할까?
앞선 방법을 통해, 호출 스택으로 확인하는 것도 좋지만, 이는 계속 오류를 일으키고 호출 스택을 확인하고의 번거로움이 있다.
다음 방법을 사용해보자.
지역에 다음 코드를 추가한다.
원래는 DBG_NEW 매크로이지만, 이렇게 사용하면, 지금 까지부터 앞으로 사용할 모든 new 키워드를 DBG_NEW으로 바꿔 사용해야 한다.
그래서 그냥 DBG_NEW를 new로 바꿔서, 기본 new 자체를 디버그 매크로로 바꿔버렸다.
이러면, 그냥 new를 사용하면 기존과 똑같지만, 자동으로 매크로 new로 치환되어 보라색 글씨로 나타나게 된다.
#ifdef _DEBUG
#define new new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
#endif
이제 추가한 코드를 실행한다.
#include <iostream>
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#ifdef _DEBUG
#define new new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
#endif
int main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
//_CrtSetBreakAlloc(79);
int* Arr = new int[10];
}
이번에는 오류 중단 없이, 프로그램이 종료되었지만, 로그에 뭔가 조금 형태로 로그가 찍혀있다.
이를 더블 클릭해 보면, 메모리 누수가 발생한 라인으로 이동하며, 하이라이트를 띄워준다.

'📕Programming > 📝C/C++' 카테고리의 다른 글
| [C / C++] 동적 라이브러리 (dynamic link library) (0) | 2025.07.18 |
|---|---|
| [C / C++] 정적 라이브러리 (static library) (0) | 2025.07.18 |
| [C / C++] C++ 동작 방식 (0) | 2025.07.15 |
| [C / C++] 인라인 함수 (in-line function) (0) | 2023.12.28 |
| [C / C++] 스마트 포인터(Smart Pointer) (0) | 2023.12.06 |