C 언어에서 메모리는 크게 두 가지 방식으로 할당할 수 있습니다. 바로 정적 메모리 할당(static memory allocation)과 동적 메모리 할당(dynamic memory allocation)입니다.
정적 메모리 할당이란?
정적 메모리 할당은 프로그램이 실행되기 전, 즉 컴파일 시점에 변수에 필요한 메모리가 고정된 크기로 한 번만 확보되는 방식을 말합니다. 한 번 할당된 메모리는 프로그램이 종료될 때까지 회수되지 않으며, 실행 중에 그 크기를 늘리거나 줄일 수도 없습니다.
선언된 변수에는 프로그램 작성 단계에서 이미 메모리가 배정되며, 다음과 같은 특징을 가집니다.
- 주소 접근: & 연산자를 사용해 변수의 주소를 얻고, 이를 포인터에 저장할 수 있습니다.
- 할당 시점: 메모리는 컴파일 시점에 할당됩니다.
- 사용 영역: 정적 메모리 할당은 스택(stack) 영역을 사용합니다.
- 크기 고정: 한 번 할당되면 메모리 크기를 변경할 수 없습니다.
- 효율성: 필요한 만큼 유연하게 사용하는 동적 할당에 비해 효율성이 떨어질 수 있습니다.
변수의 최종 크기가 프로그램 실행 전에 결정되기 때문에 '정적' 메모리 할당이라 부르며, 이를 컴파일 타임 메모리 할당(compile-time memory allocation)이라고도 합니다. 따라서 컴파일 시점에 할당된 변수의 크기는 실행 중에 절대 변경할 수 없습니다.
예제 1 — 배열로 살펴보는 정적 메모리 할당
정적 메모리 할당의 대표적인 활용 사례는 배열입니다. 배열은 선언 시 크기를 지정하며, 이 크기는 컴파일 시점에 고정됩니다.
#include <stdio.h>
int main() {
int a[5] = {10, 20, 30, 40, 50}; // 크기가 5로 고정된 정적 배열
int i;
printf("배열의 요소는 다음과 같습니다:\n");
for (i = 0; i < 5; i++)
printf("%d ", a[i]);
return 0;
}
실행 결과
배열의 요소는 다음과 같습니다: 10 20 30 40 50
예제 2 — 배열 요소의 합과 곱 구하기
다음 예제는 정적으로 선언된 배열의 모든 요소를 더하고 곱한 결과를 출력합니다.
#include <stdio.h>
int main() {
// 배열 선언 및 초기화 (컴파일 시점에 크기 결정)
int array[5] = {10, 20, 30, 40, 50};
int i, sum = 0, product = 1;
// 반복문으로 각 요소를 순회하며 합과 곱 계산
for (i = 0; i < 5; i++) {
sum += array[i];
product *= array[i];
}
// 결과 출력
printf("배열 요소의 합 : %d\n", sum);
printf("배열 요소의 곱 : %d\n", product);
return 0;
}
실행 결과
배열 요소의 합 : 150 배열 요소의 곱 : 12000000
마무리: 정적 할당 vs 동적 할당
정적 메모리 할당은 속도가 빠르고 관리가 간단하지만, 크기를 미리 알아야 하고 유연성이 떨어진다는 한계가 있습니다. 반면 malloc(), calloc() 같은 함수를 이용한 동적 메모리 할당은 힙(heap) 영역에서 실행 시점에 크기를 조절할 수 있어 유연하지만, free()로 직접 해제해야 하는 관리 책임이 따릅니다. 따라서 크기가 고정된 데이터는 정적 할당, 실행 중 크기가 변하는 데이터는 동적 할당을 사용하는 것이 효과적입니다.