C언어 동적 메모리 할당 (malloc, free)
요약
C언어 동적 메모리 할당의 기본 개념, malloc()과 free() 함수 사용법을 알아봅니다. 정보처리기사 실기에 자주 출제되는 동적 메모리 할당 문제를 풀기 위한 핵심 개념을 정리합니다.
동적 메모리 할당 핵심 정리
| 개념 | 설명 | 예시 |
|---|---|---|
malloc() | 힙 메모리에서 지정한 크기만큼 할당 | malloc(sizeof(int)) |
sizeof() | 자료형의 크기(바이트)를 반환 | sizeof(int) = 4 |
| 형변환 | malloc 반환값을 원하는 포인터 타입으로 변환 (생략 가능) | (int*)malloc(...) |
free() | 할당된 메모리를 해제 | free(p); |
동적 메모리 할당이란? 기초
동적 메모리 할당은 프로그램 실행 중에 필요한 만큼 메모리를 할당받는 방법입니다.
일반 변수는 스택(Stack) 에 저장되고 크기가 컴파일 시점에 결정됩니다. 반면 동적 메모리는 힙(Heap) 에 저장되고 런타임에 크기를 결정할 수 있습니다. 자세한 내용은 메모리 구조를 참고하세요.

| 구분 | 스택 메모리 | 힙 메모리 |
|---|---|---|
| 할당 시점 | 컴파일 시 | 실행 시 |
| 크기 결정 | 고정 | 가변 |
| 해제 | 자동 (함수 종료 시) | 수동 (free 호출) |
| 예시 | int arr[10]; | malloc(sizeof(int)*10) |
malloc() 함수 기초
**malloc()**은 Memory Allocation의 약자로, 힙 메모리에서 지정한 바이트만큼 공간을 할당합니다. 사용하려면 #include <stdlib.h>가 필요합니다.

malloc() 사용 패턴
sizeof() 연산자
sizeof()는 자료형이나 변수의 크기를 바이트 단위로 반환합니다.
| 자료형 | sizeof() 결과 |
|---|---|
char | 1 바이트 |
int | 4 바이트 |
float | 4 바이트 |
double | 8 바이트 |
포인터 | 4 또는 8 바이트 (시스템에 따라) |
형변환 (Casting) 기초
malloc()은 void* 타입을 반환합니다. void*는 "아직 타입이 정해지지 않은 범용 주소"로, 어떤 포인터 타입으로든 변환할 수 있습니다.
void*는 다른 포인터 타입으로 자동 변환되므로, 형변환을 생략해도 됩니다.
2차원 배열 동적 할당 심화
2차원 배열을 동적으로 할당하려면 이중 포인터를 사용합니다.

2차원 배열 해제
할당의 역순으로 해제해야 합니다. 행 포인터 배열(arr)을 먼저 해제하면 각 행 데이터(arr[0], arr[1], ...)의 주소를 잃어버려서 해제할 수 없게 됩니다.
정적 2차원 배열과의 차이
정적 2차원 배열 int a[3][3]은 메모리가 연속된 한 블록으로 잡히므로, a와 a[0]과 &a[0][0]이 모두 같은 주소를 가리킵니다 (타입만 다름).

반면 동적 할당 int **arr은 malloc을 여러 번 따로 호출하기 때문에 각각 독립적인 메모리 블록이 생깁니다.

동적 할당에서 arr[0]은 행 포인터 배열에 저장된 포인터 변수이고, arr[0][0]은 별도로 할당된 데이터 블록의 첫 번째 원소입니다. 각 malloc 호출이 서로 다른 메모리 영역을 반환하므로, 이 주소들은 절대 같을 수 없습니다.

free() 함수 기초
**free()**는 malloc()으로 할당한 메모리를 해제합니다. 해제하지 않으면 메모리 누수(Memory Leak) 가 발생합니다. 메모리 누수란 프로그램이 더 이상 쓰지 않는 메모리를 반환하지 않아, 프로그램이 실행될수록 사용 가능한 메모리가 줄어드는 현상입니다.

연결 리스트에서의 활용 심화
동적 메모리 할당은 연결 리스트에서 노드 1를 생성할 때 주로 사용됩니다.
-> 는 포인터가 가리키는 구조체의 멤버에 접근하는 연산자입니다. n->c는 (*n).c와 같은 의미입니다.
연결 리스트 삽입 예시
이 함수는 새 노드를 리스트의 맨 앞에 삽입합니다. 구조체 포인터와 함께 사용되는 패턴을 익혀두세요.
정보처리기사 실기 대비 문제
Footnotes
-
데이터와 다음 노드의 주소를 함께 담는 구조체 단위. 연결 리스트의 기본 구성 요소입니다. ↩