Core Programming/C Standard Library: Resource & Performan

C언어 동적 메모리 할당 총정리: malloc, calloc, realloc, free 완벽 가이드

임베디드 친구 2025. 2. 17. 09:17
반응형

C언어 동적 메모리 할당 완벽 가이드: malloc부터 free까지

C언어 프로그래밍에서 효율적인 자원 관리는 필수입니다. 정적 배열의 한계를 넘어 실행 중에 메모리 크기를 결정하는 동적 메모리 할당(Dynamic Memory Allocation)은 고급 개발자로 나아가기 위한 필수 관문입니다.

오늘은 stdlib.h 라이브러리가 제공하는 동적 할당 함수들의 특징과 실무 사용법을 정리해 드립니다.

Generated by Gemini AI.


1. 동적 메모리 할당이란?

C언어의 일반적인 변수는 스택(Stack) 영역에 저장되어 선언 시 크기가 고정됩니다. 반면, 동적 할당은 힙(Heap) 영역을 사용하며 프로그램 실행(Runtime) 중에 필요한 만큼 메모리를 요청합니다.

구분 정적 할당 (Static) 동적 할당 (Dynamic)
저장 위치 스택 (Stack) 힙 (Heap)
결정 시기 컴파일 타임 런타임
장점 관리가 자동임 (빠름) 유연한 크기 조절 가능
단점 크기 변경 불가 수동 해제 필요 (관리 주의)

2. stdlib.h 주요 동적 할당 함수

2.1 malloc: 메모리 할당의 기본

가장 많이 사용되는 함수로, 지정한 바이트만큼 메모리를 할당합니다. 내부 값은 초기화되지 않아 쓰레기 값이 들어있을 수 있습니다.

C
 
#include <stdio.h>
#include <stdlib.h>

int main() {
    int *arr;
    int n = 5;

    // n개의 정수 크기만큼 힙 메모리 할당
    arr = (int *)malloc(n * sizeof(int));

    if (arr == NULL) { // 할당 실패 예외 처리 필수!
        fprintf(stderr, "메모리 할당 실패\n");
        return 1;
    }

    for (int i = 0; i < n; i++) arr[i] = i + 1;
    
    free(arr); // 사용 후 반드시 해제
    return 0;
}

2.2 calloc: 0으로 초기화된 할당

할당과 동시에 모든 비트를 0으로 초기화합니다. 행렬 계산이나 초기값이 중요한 구조체 할당에 유리합니다.

C
 
// n개의 요소를 각각 size 크기로 할당하고 0으로 초기화
int *arr = (int *)calloc(5, sizeof(int));

2.3 realloc: 메모리 크기 재조정

이미 할당된 메모리의 크기를 줄이거나 늘릴 때 사용합니다. 기존 데이터는 최대한 유지됩니다.

C
 
// 기존 arr의 크기를 10개로 확장
int *new_arr = (int *)realloc(arr, 10 * sizeof(int));
if (new_arr != NULL) arr = new_arr; // 재할당 성공 시 포인터 업데이트

3. 실무에서 가장 중요한 'free'와 메모리 관리

동적 할당된 메모리는 개발자가 직접 해제하기 전까지 시스템에 남아 있습니다. 이를 해제하지 않으면 메모리 누수(Memory Leak)가 발생하여 시스템이 느려지거나 다운될 수 있습니다.

안전한 메모리 해제 패턴

C
 
free(ptr);
ptr = NULL; // 댕글링 포인터(Dangling Pointer) 방지

Tip: free를 한 후 포인터를 NULL로 밀어주는 습관은 이미 해제된 메모리에 다시 접근하는 실수를 원천 차단합니다.


4. 핵심 요약 및 주의사항 (Checklist)

  1. 반드시 NULL 체크: 메모리가 부족할 경우 malloc은 NULL을 반환합니다. 이를 체크하지 않고 접근하면 Segmentation Fault가 발생합니다.
  2. 형변환(Casting): malloc은 void *를 반환하므로 사용하려는 포인터 타입으로 형변환 해주는 것이 가독성에 좋습니다. (예: (int *)malloc(...))
  3. sizeof 활용: 하드웨어 아키텍처에 따라 자료형의 크기가 다를 수 있으므로, malloc(20) 보다는 malloc(5 * sizeof(int)) 처럼 작성하는 것이 이식성에 좋습니다.
  4. 한 번만 free: 이미 해제된 메모리를 두 번 free 하는 것은 치명적인 오류를 야기합니다.

마무리하며

동적 메모리 할당은 강력한 도구이지만, 그만큼 책임이 따릅니다. 특히 임베디드 시스템처럼 리소스가 한정적인 환경에서는 malloc 사용을 최소화하거나 철저하게 관리해야 합니다. 위 원칙들을 지키며 더 유연하고 견고한 코드를 작성해 보세요!


포스팅이 도움이 되셨다면 하트(♥)와 댓글 부탁드립니다!

임베디드 소프트웨어 및 최적화 기법에 대한 전문적인 정보는 'Coding by Head' 블로그에서 계속됩니다.

https://coding-by-head.tistory.com/

반응형