고급 C 프로그래밍 – 동적 메모리 할당과 관리 – 0 – malloc, calloc, realloc, free 함수

고급 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 체크, freeNULL 설정, 메모리 누수 방지

마무리하며 💬

동적 메모리 할당은 C 언어의 진정한 실력을 가늠하는 척도라고 해도 과언이 아니에요.
효율적인 메모리 관리는 프로그램의 성능과 안정성을 좌우하는 핵심 요소랍니다!

🎯 “malloc으로 공간을 만들고, calloc으로 깨끗하게 채우고,
realloc으로 넓히고, free로 반드시 정리하자!”

다음 시간에는 동적 메모리를 더 안전하게 다루기 위한
메모리 오류 디버깅 기법과 유용한 패턴들을 소개해드릴게요!
계속해서 함께 공부해요! 💻🔥

답글 남기기