메모리 누수(memory leak)는 프로그래머가 힙(heap) 영역에 동적으로 할당한 메모리를 프로그램에서 더 이상 사용하지 않게 된 후에도 적절히 해제(deallocate)하지 않을 때 발생하는 문제입니다. 해제되지 않은 메모리는 아무 용도 없이 계속 점유된 상태로 남기 때문에 '누수'라고 부릅니다.
메모리 누수가 문제가 되는 이유
메모리 누수가 발생하면 일부 메모리 블록이 낭비됩니다. 시스템에 여유 메모리가 충분하더라도 누수가 반복되면 사용 가능한 메모리가 점점 줄어들어 프로그램 성능 저하를 유발하고, 심한 경우 장시간 실행되는 서버나 임베디드 시스템에서는 메모리 고갈로 인한 비정상 종료(OOM)까지 일으킬 수 있습니다.
예제 1: C++에서 new 후 delete 누락
void my_func() {
int *data = new int; // 힙에 int 하나 할당
*data = 50;
} // 함수가 끝나도 delete가 호출되지 않음 → 메모리 누수!이 코드의 문제점은 data 포인터가 가리키는 메모리를 delete로 해제하지 않고 함수가 종료된다는 것입니다. 함수가 반환되면 포인터 변수 자체는 사라지지만, 힙에 할당된 메모리는 그대로 남아 있어 더 이상 접근할 수 없는 상태가 됩니다.
해결 방법
void my_func() {
int *data = new int;
*data = 50;
delete data; // 사용 후 반드시 해제
}예제 2: C에서 malloc 후 free 누락
#include <stdio.h>
#include <stdlib.h>
void leak() {
int *ptr = (int *)malloc(sizeof(int) * 100);
if (ptr == NULL) return;
ptr[0] = 10;
// free(ptr); 가 없어 매 호출마다 400바이트씩 누수
}
int main(void) {
for (int i = 0; i < 1000; i++) {
leak(); // 총 약 400KB 누수
}
printf("Done\n");
return 0;
}반복문 안에서 계속 메모리를 할당만 하고 해제하지 않으면, 프로그램이 실행되는 동안 누수량이 누적되어 성능 저하와 메모리 부족으로 이어질 수 있습니다.
메모리 누수 예방 팁
- 할당과 해제의 짝 맞추기:
new에는delete,malloc/calloc/realloc에는free를 반드시 짝지어 호출합니다. - 스마트 포인터 활용(C++):
std::unique_ptr,std::shared_ptr등을 사용하면 스코프가 끝날 때 자동으로 메모리가 해제됩니다. - RAII 패턴 적용: 자원의 획득과 해제를 객체의 생성과 소멸에 연결하면 예외 상황에서도 누수를 방지할 수 있습니다.
- 정적 분석 및 검증 도구 사용: Valgrind, AddressSanitizer(ASan) 같은 도구로 누수 위치를 손쉽게 진단할 수 있습니다.
메모리 누수는 컴파일 타임에 잡히지 않는 대표적인 런타임 결함입니다. 동적 할당을 사용하는 모든 코드 경로에서 해제 로직을 꼼꼼히 점검하고, 가능하면 스마트 포인터와 검증 도구를 활용하는 습관이 안정적인 C/C++ 프로그램 작성의 핵심입니다.