고급 C 프로그래밍 – 동적 메모리 할당과 관리 – 0편: malloc, calloc, realloc, free 함수 완전 정복
안녕하세요, 여러분! 😊
이번에는 C 언어 고급 프로그래밍에서 가장 실용적이고 중요한 기술 중 하나인
**동적 메모리 할당(Dynamic Memory Allocation)**에 대해 배워볼 거예요!
💡 “프로그램 실행 중에 메모리를 유연하게 쓰고 싶다!”
그럴 땐 정적인 배열 대신, 동적으로 메모리를 빌려오는 방식이 필요하답니다.
C 언어에서는 malloc
, calloc
, realloc
, free
라는 네 친구를 통해
이 기능을 마음껏 활용할 수 있어요.
그럼 하나씩 알아보면서, 진짜 프로답게 메모리를 다뤄볼까요? 😎
1. 동적 메모리 할당이란?
동적 메모리 할당이란, 프로그램이 실행되는 도중에
필요한 만큼의 메모리를 런타임에 확보하는 기능입니다.
왜 필요할까요?
정적 메모리 (배열 등) | 동적 메모리 |
---|---|
컴파일 시 크기 고정 | 실행 중 크기 결정 가능 |
메모리 낭비 가능성 | 필요한 만큼만 사용 |
유연성 부족 | 유연하고 확장 가능 |
📦 마치 이사할 때 가구를 맞춤 제작하듯,
필요한 공간만큼만 딱 빌려쓰는 방식이죠!
2. malloc()
함수 – 메모리 할당의 기본
문법
void* malloc(size_t size);
size
: 할당할 바이트 수- 반환값: 할당된 메모리 주소 (void 포인터)
예시
int *arr = (int*) malloc(5 * sizeof(int));
int
5개 = 20바이트 (4바이트 × 5)- 반환된 포인터를
int*
로 형변환해서 사용
주의점
- 초기화되지 않은 쓰레기 값으로 채워짐!
- 반드시
NULL
체크!
if (arr == NULL) {
printf("메모리 할당 실패!
");
}
3. calloc()
함수 – 0으로 초기화된 메모리 할당
문법
void* calloc(size_t num, size_t size);
num
: 요소 수size
: 각 요소의 크기
예시
int *arr = (int*) calloc(5, sizeof(int));
int
5개 = 20바이트를 0으로 초기화해서 할당
🎯
calloc()
은malloc()
+memset(ptr, 0, size)
의 조합이라고 보면 돼요!
4. realloc()
함수 – 크기 재조정
문법
void* realloc(void* ptr, size_t new_size);
- 기존 포인터의 크기를 늘리거나 줄이는 함수
- 데이터를 보존하면서 다른 위치로 복사 후 새 포인터 반환 가능성 있음!
예시
int *arr = (int*) malloc(5 * sizeof(int));
arr = (int*) realloc(arr, 10 * sizeof(int));
🧠 배열을 확장할 때 매우 유용한 함수!
기존 값을 유지하면서 크기를 유동적으로 바꿀 수 있어요.
5. free()
함수 – 메모리 반환
문법
void free(void* ptr);
malloc
,calloc
,realloc
으로 얻은 메모리는
반드시free()
로 해제해야 메모리 누수를 막을 수 있어요!
예시
free(arr);
arr = NULL; // 사용 금지 방지
💥 해제 후에는 꼭 NULL로 초기화해 주세요!
그렇지 않으면 dangling pointer(죽은 포인터) 문제가 생길 수 있어요.
6. 실전 예제: 배열을 동적으로 생성하고 확장하기
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr = (int*) malloc(3 * sizeof(int));
if (!arr) {
printf("할당 실패
");
return 1;
}
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
arr = (int*) realloc(arr, 5 * sizeof(int));
arr[3] = 40;
arr[4] = 50;
for (int i = 0; i < 5; i++)
printf("%d ", arr[i]);
printf("
");
free(arr);
return 0;
}
📈 동적 배열처럼 유동적으로 메모리를 늘릴 수 있죠!
7. 함수별 비교 요약표
함수 | 초기화 | 크기 조절 | 사용 목적 |
---|---|---|---|
malloc() |
❌ (쓰레기값) | ❌ | 일반 메모리 할당 |
calloc() |
✅ (0으로) | ❌ | 초기화된 메모리 |
realloc() |
– | ✅ | 메모리 재할당 |
free() |
– | – | 메모리 해제 |
8. 메모리 누수(Memory Leak)에 주의하세요!
🧠 메모리 누수란?
할당된 메모리를 해제하지 않고 계속 사용하는 버그!
잘못된 예
void func() {
int *temp = malloc(100);
// free(temp); ← 없음! 누수 발생
}
- 이런 코드가 반복되면 프로그램 종료 시점에 수십, 수백 MB의 누수 발생 가능
9. 포인터 체크 팁
int *ptr = malloc(sizeof(int));
if (ptr == NULL) {
fprintf(stderr, "할당 실패
");
exit(1);
}
- 항상 NULL 체크 후 사용!
free()
이후에는 꼭ptr = NULL;
로 설정!
✅ 요약 정리
키워드 | 설명 |
---|---|
malloc(size) |
지정한 바이트 수만큼 메모리 할당 |
calloc(n, size) |
초기화된 메모리 할당 |
realloc(ptr, new_size) |
메모리 재할당 |
free(ptr) |
할당된 메모리 해제 |
주의사항 | NULL 체크, free 후 NULL 설정, 메모리 누수 방지 |
마무리하며 💬
동적 메모리 할당은 C 언어의 진정한 실력을 가늠하는 척도라고 해도 과언이 아니에요.
효율적인 메모리 관리는 프로그램의 성능과 안정성을 좌우하는 핵심 요소랍니다!
🎯 “malloc으로 공간을 만들고, calloc으로 깨끗하게 채우고,
realloc으로 넓히고, free로 반드시 정리하자!”
다음 시간에는 동적 메모리를 더 안전하게 다루기 위한
메모리 오류 디버깅 기법과 유용한 패턴들을 소개해드릴게요!
계속해서 함께 공부해요! 💻🔥