동적 메모리 할당 — malloc과 free
이 토픽을 마치면
스택과 힙 메모리의 차이, 동적 할당이 왜 필요한지, 그리고 메모리 누수가 왜 발생하는지 이해합니다.
두 종류의 메모리
프로그램이 쓰는 메모리는 크게 **스택(Stack)**과 힙(Heap) 두 영역으로 나뉩니다.
높은 주소 ┌──────────────┐
│ 스택 │ ← 함수 호출할 때마다 자동 할당/해제
│ ↓ 아래로 │
│ │
│ │
│ ↑ 위로 │
│ 힙 │ ← 프로그래머가 직접 할당/해제
낮은 주소 └──────────────┘| 스택 | 힙 | |
|---|---|---|
| 할당 | 자동 (함수 호출 시) | 수동 (malloc) |
| 해제 | 자동 (함수 종료 시) | 수동 (free) |
| 크기 | 작고 고정적 (보통 수 MB) | 크고 유동적 (RAM 한도) |
| 속도 | 매우 빠름 | 약간 느림 |
| 용도 | 지역 변수, 함수 인자 | 크기가 미정인 데이터 |
왜 동적 할당이 필요한가
스택에 변수를 만들면 크기를 컴파일 시점에 알아야 합니다:
int arr[100]; // 100개 — 컴파일할 때 결정하지만 사용자가 "몇 개의 데이터를 입력할 건가요?"라고 물으면, 프로그램이 실행되기 전에는 알 수 없습니다. 이럴 때 동적 할당을 씁니다:
int n;
printf("몇 개? ");
scanf("%d", &n);
int *arr = malloc(n * sizeof(int)); // 실행 중에 n개만큼 할당malloc(memory allocation)은 힙에서 요청한 바이트만큼 메모리를 가져옵니다.
malloc과 free
#include <stdlib.h>
// 할당
int *data = malloc(5 * sizeof(int));
// 사용
for (int i = 0; i < 5; i++) {
data[i] = i * 10;
}
// 해제
free(data);
data = NULL; // 안전을 위해 NULL로 설정malloc이 메모리를 주면 쓸 수 있고, 다 쓰면 free로 돌려줘야 합니다. free를 안 하면 그 메모리는 프로그램이 끝날 때까지 반환되지 않습니다.
메모리 누수
void process() {
int *data = malloc(1000000 * sizeof(int));
// 데이터 처리...
if (error) {
return; // free 안 하고 빠져나감!
}
free(data);
}이 함수가 에러로 빠져나가면 free가 실행되지 않습니다. 100만 개의 int(약 4MB)가 돌아오지 않습니다. 이 함수가 1000번 호출되면 4GB가 새어나갑니다. 이것이 **메모리 누수(memory leak)**입니다.
메모리 누수는 프로그램이 즉시 죽지 않아서 위험합니다. 서서히 메모리를 먹다가 시스템 전체가 느려지고, 결국 OOM(Out of Memory)으로 죽습니다. 서버 프로그램에서는 며칠 뒤에 갑자기 죽는 원인이 되기도 합니다.
고급 언어의 해결 — 가비지 컬렉션
Python, JavaScript, Java, Go는 **가비지 컬렉터(GC)**가 알아서 해제합니다:
def process(): data = [0] * 1000000 # 함수 끝나면 data를 참조하는 변수가 없어짐 # → GC가 자동으로 메모리 회수프로그래머가 free를 호출할 필요가 없습니다. GC가 "이 메모리를 가리키는 변수가 아무도 없네?"를 주기적으로 검사하고 회수합니다.
대가가 있습니다:
| 수동 (C) | 자동 (Python/Java) | |
|---|---|---|
| 메모리 누수 가능성 | 높음 (프로그래머 실수) | 낮음 (GC가 처리) |
| 성능 | 예측 가능 | GC 실행 시 잠깐 멈출 수 있음 |
| 코드 복잡도 | 높음 (free 관리) | 낮음 (신경 안 써도 됨) |
Rust는 제3의 길을 택했습니다 — GC도 없고 수동 free도 없이, 컴파일러가 변수의 수명을 추적해서 자동으로 해제 코드를 넣어줍니다.
핵심
스택은 자동으로 할당/해제되고, 힙은 프로그래머가 직접 관리합니다.
malloc으로 힙에 할당하고,free로 반환 — 빠뜨리면 메모리 누수. 고급 언어는 GC로 이 문제를 자동 해결하지만, 왜 메모리 관리가 필요한지 아는 것이 CS의 기초입니다.