C 언어에서 동적 메모리 할당은 프로그램 실행 중에 필요한 만큼 메모리를 유연하게 확보할 수 있게 해주는 핵심 기능입니다. 이를 담당하는 대표적인 함수가 바로 malloc()과 free()이며, 두 함수는 모두 <stdlib.h> 헤더 파일에 선언되어 있습니다.
malloc() 함수란?
malloc()(memory allocation)은 요청한 크기만큼의 바이트를 힙(heap) 영역에 할당하고, 할당된 메모리의 첫 번째 바이트를 가리키는 포인터를 반환합니다. 만약 메모리 할당에 실패하면 NULL 포인터를 반환하므로, 반드시 반환값을 확인해야 합니다.
malloc() 문법
pointer_name = (cast-type*) malloc(size);
각 구성 요소의 의미는 다음과 같습니다.
pointer_name − 할당된 메모리를 가리킬 포인터 변수의 이름입니다.
cast-type − malloc()이 할당한 메모리를 변환(cast)하고자 하는 데이터 타입입니다.
size − 할당할 메모리의 크기(바이트 단위)입니다.
malloc() 사용 예제
다음은 malloc()으로 정수 4개를 저장할 배열을 동적으로 생성하고, 입력받은 값들의 합을 출력하는 예제입니다.
#include <stdio.h>
#include <stdlib.h>
int main() {
int n = 4, i, *p, s = 0;
p = (int*) malloc(n * sizeof(int));
if(p == NULL) {
printf("\nError! memory not allocated.");
exit(0);
}
printf("\nEnter elements of array : ");
for(i = 0; i < n; ++i) {
scanf("%d", p + i);
s += *(p + i);
}
printf("\nSum : %d", s);
return 0;
}실행 결과
Enter elements of array : 32 23 21 8 Sum : 84
free() 함수란?
free()는 malloc() 등으로 할당된 메모리를 해제하는 함수입니다. 메모리를 운영체제에 즉시 반환하지 않고 재사용 가능한 상태로 만들며, 이후 다른 동적 할당 요청 시 해당 공간이 활용될 수 있습니다.
주의할 점은 free() 호출 후에도 포인터 변수 자체의 값은 그대로 유지된다는 것입니다. 즉, 포인터는 여전히 같은 메모리 위치를 가리키고 있지만, 그 메모리는 이미 해제되었으므로 접근해서는 안 됩니다. 이러한 포인터를 댕글링 포인터(dangling pointer)라고 하며, 안전성을 위해 해제 후 NULL로 초기화하는 것이 좋습니다.
free() 문법
void free(void *pointer_name);
pointer_name − 해제할 메모리를 가리키는 포인터의 이름입니다.
free() 사용 예제
앞선 예제에 free()를 추가하여 사용이 끝난 메모리를 명시적으로 해제하는 모습입니다.
#include <stdio.h>
#include <stdlib.h>
int main() {
int n = 4, i, *p, s = 0;
p = (int*) malloc(n * sizeof(int));
if(p == NULL) {
printf("\nError! memory not allocated.");
exit(0);
}
printf("\nEnter elements of array : ");
for(i = 0; i < n; ++i) {
scanf("%d", p + i);
s += *(p + i);
}
printf("\nSum : %d", s);
free(p);
return 0;
}실행 결과
Enter elements of array : 32 23 21 28 Sum : 104
정리 및 주의사항
malloc()으로 할당한 메모리는 사용이 끝나면 반드시 free()로 해제해야 합니다. 해제하지 않으면 메모리 누수(memory leak)가 발생합니다.
같은 포인터에 대해 free()를 두 번 호출하면 정의되지 않은 동작(undefined behavior)이 일어날 수 있습니다.
malloc()의 반환값은 항상 NULL 여부를 검사한 뒤 사용하는 것이 안전합니다.
필요하다면 초기화된 메모리를 할당하는 calloc(), 크기를 조절하는 realloc()도 함께 활용할 수 있습니다.