c 언어/c 표준 라이브러리(Standard C Library)

C `stdlib.h` 개요 및 동적 메모리 할당

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

1. stdlib.h 개요

C 언어의 표준 라이브러리인 stdlib.h는 다양한 유틸리티 함수들을 제공하며, 그중에서도 동적 메모리 할당 관련 함수들이 핵심적인 역할을 합니다.

stdlib.h에서 제공하는 주요 기능은 다음과 같습니다.

  • 동적 메모리 할당 (malloc, calloc, realloc, free)
  • 난수 생성 (rand, srand)
  • 문자열 변환 (atoi, atof, strtol, strtod 등)
  • 프로세스 제어 (exit, abort, system)

이번 포스팅에서는 동적 메모리 할당 관련 함수들을 중심으로 설명하겠습니다.


2. 동적 메모리 할당의 필요성

C 언어에서는 배열을 사용할 경우 크기를 미리 지정해야 합니다. 하지만 프로그램 실행 중에 필요한 크기를 예측하기 어려운 경우가 많습니다.
이럴 때 동적 메모리 할당을 사용하면 런타임에 원하는 크기의 메모리를 할당받고 유연하게 사용할 수 있습니다.

C 언어에서 동적 메모리 할당을 위한 주요 함수는 다음과 같습니다.

함수 설명
malloc(size_t size) 지정한 바이트 크기의 메모리를 할당하고 포인터 반환
calloc(size_t num, size_t size) num 개의 요소를 할당하고 0으로 초기화하여 포인터 반환
realloc(void *ptr, size_t size) 기존 메모리를 새로운 크기로 재할당
free(void *ptr) 할당된 메모리를 해제

3. 동적 메모리 할당 함수 사용 예제

3.1 malloc 사용 예제

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

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

    // n개의 정수를 저장할 메모리 할당
    arr = (int *)malloc(n * sizeof(int));
    if (arr == NULL) {
        printf("메모리 할당 실패\n");
        return 1;
    }

    for (int i = 0; i < n; i++) {
        arr[i] = i * 10;
    }

    for (int i = 0; i < n; i++) {
        printf("arr[%d] = %d\n", i, arr[i]);
    }

    free(arr); // 메모리 해제
    return 0;
}

설명:

  • malloc(n * sizeof(int))을 사용하여 n개의 정수를 저장할 수 있는 메모리를 할당합니다.
  • 할당된 메모리의 유효성을 검사한 후 사용합니다.
  • 사용이 끝난 메모리는 반드시 free()를 호출하여 해제해야 합니다.

3.2 calloc 사용 예제

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

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

    arr = (int *)calloc(n, sizeof(int));
    if (arr == NULL) {
        printf("메모리 할당 실패\n");
        return 1;
    }

    for (int i = 0; i < n; i++) {
        printf("arr[%d] = %d\n", i, arr[i]); // 초기화 확인
    }

    free(arr); // 메모리 해제
    return 0;
}

설명:

  • calloc(n, sizeof(int))을 사용하면 n개의 정수를 저장할 메모리를 할당하고 0으로 초기화합니다.
  • malloc과 다르게 초기화된 상태로 사용할 수 있습니다.

3.3 realloc 사용 예제

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

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

    arr = (int *)malloc(n * sizeof(int));
    if (arr == NULL) {
        printf("메모리 할당 실패\n");
        return 1;
    }

    for (int i = 0; i < n; i++) {
        arr[i] = i * 10;
    }

    // 배열 크기 확장
    n = 10;
    arr = (int *)realloc(arr, n * sizeof(int));
    if (arr == NULL) {
        printf("메모리 재할당 실패\n");
        return 1;
    }

    for (int i = 5; i < n; i++) {
        arr[i] = i * 10;
    }

    for (int i = 0; i < n; i++) {
        printf("arr[%d] = %d\n", i, arr[i]);
    }

    free(arr);
    return 0;
}

설명:

  • realloc을 사용하여 메모리를 재할당합니다.
  • realloc 호출 후 반환된 포인터를 기존 포인터에 할당해야 합니다.
  • 기존 데이터는 유지되지만, 새로운 메모리의 값은 초기화되지 않음에 주의해야 합니다.

3.4 free 사용 예제

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

int main() {
    int *ptr = (int *)malloc(10 * sizeof(int));
    if (ptr == NULL) {
        printf("메모리 할당 실패\n");
        return 1;
    }

    free(ptr);
    ptr = NULL; // 해제 후 NULL로 설정하는 것이 좋음

    return 0;
}

설명:

  • free(ptr)을 호출하여 동적 할당된 메모리를 해제합니다.
  • free() 후에는 해당 포인터를 NULL로 설정하는 것이 좋습니다.
  • 해제된 메모리를 다시 접근하면 미정의 동작(Undefined Behavior)이 발생할 수 있습니다.

4. 정리 및 주의사항

  • malloc은 메모리를 할당하지만 초기화하지 않습니다.
  • calloc은 할당된 메모리를 0으로 초기화합니다.
  • realloc은 기존 데이터를 유지한 채 메모리 크기를 조정할 수 있습니다.
  • 동적 할당된 메모리는 반드시 free()를 호출하여 해제해야 합니다.
  • free() 이후 해당 포인터를 NULL로 설정하는 것이 권장됩니다.
  • 해제된 메모리에 접근하면 미정의 동작이 발생하므로 주의해야 합니다.

이상으로 stdlib.h의 동적 메모리 할당 함수들에 대해 알아보았습니다. 감사합니다!

반응형