산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Industrial programming >> C 언어

C 동적 메모리 할당: malloc, calloc, realloc, free 완벽 마스터

C에서 동적 메모리 할당을 다루기 전에 C에서 메모리가 어떻게 관리되는지 이해하는 것이 필수적입니다.

C에서 메모리 관리 작동 원리

기본 타입으로 변수를 선언하면 컴파일러가 스택에 자동으로 공간을 할당합니다. 예를 들어 float는 일반적으로 4바이트(플랫폼 의존)를 차지합니다. sizeof 연산자로 확인 가능:

#include <stdio.h>
int main() {
    float x;
    printf("The size of float is %d bytes", sizeof(x));
    return 0;
}

출력:

The size of float is 4 bytes

지정된 크기의 배열도 스택에 연속적으로 할당되며, 각 요소는 해당 타입 크기를 차지합니다:

#include <stdio.h>
int main() {
    float arr[10];
    printf("The size of the float array with 10 elements is %d", sizeof(arr));
    return 0;
}

결과:

The size of the float array with 10 elements is 40

스택 할당은 자동이지만, 많은 프로그램은 런타임까지 크기를 알 수 없는 메모리를 필요로 합니다. 이 필요를 동적 메모리 할당이 해결하며, 스택 대신 힙을 사용합니다.

C 동적 메모리 할당

동적 할당은 필요에 따라 메모리를 수동으로 요청하고 해제하며, 포인터로 힙의 할당 블록을 추적합니다. C 표준 라이브러리는 이를 위한 여러 함수를 제공:

각 함수를 자세히 살펴봅시다.

malloc() 함수

malloc()은 "memory allocation"을 의미합니다. 지정된 크기의 메모리 블록을 예약하고 이에 대한 포인터를 반환합니다. 포인터는 보통 원하는 타입으로 캐스팅:

ptr = (캐스트_타입 *) malloc(바이트_크기);

예제:

#include <stdlib.h>
int main(){
    int *ptr;
    ptr = malloc(15 * sizeof(*ptr)); /* 15개 정수 */
    if (ptr != NULL) {
        *(ptr + 5) = 480; /* 6번째 요소 */
        printf("Value of the 6th integer is %d", *(ptr + 5));
    }
}

출력:

Value of the 6th integer is 480

핵심 포인트:

  1. sizeof(*ptr) 사용으로 타입 변경에 강건한 코드 작성
  2. NULL 반환 확인으로 할당 실패 감지
  3. 할당 메모리는 연속적; 배열처럼 다루고 포인터 연산 사용

동적 할당은 기본 타입뿐 아니라 구조체, 문자 배열 등에도 적용 가능.

free() 함수

malloc(), calloc(), realloc()로 할당된 메모리는 누수 방지를 위해 명시적으로 해제해야 합니다. free()가 이 작업을 수행:

#include <stdio.h>
int main() {
    int* ptr = malloc(10 * sizeof(*ptr));
    if (ptr != NULL){
        *(ptr + 2) = 50;
        printf("Value of the 2nd integer is %d", *(ptr + 2));
    }
    free(ptr);
}

출력:

Value of the 2nd integer is 50

calloc() 함수

calloc()은 동일한 크기의 여러 블록을 할당하고 모든 바이트를 0으로 초기화하므로, 제로 초기화가 필요한 배열과 구조체에 이상적:

ptr = (캐스트_타입 *) calloc(n, 크기);

예제 – 등차수열 합계:

#include <stdio.h>
int main() {
    int i, *ptr, sum = 0;
    ptr = calloc(10, sizeof(int));
    if (ptr == NULL) {
        printf("Error! memory not allocated.");
        exit(0);
    }
    for (i = 0; i < 10; ++i) {
        *(ptr + i) = i;
        sum += *(ptr + i);
    }
    printf("Sum = %d", sum);
    free(ptr);
    return 0;
}

결과:

Sum = 45

calloc() vs malloc()

주요 차이점:

realloc() 함수

realloc()은 기존 할당 크기를 변경하면서 내용 보존:

ptr = realloc(ptr, 새_크기);

예제 – 문자열 버퍼 확장:

#include <stdio.h>
int main () {
    char *ptr = malloc(10);
    strcpy(ptr, "Programming");
    ptr = realloc(ptr, 20); // 확대
    strcat(ptr, " In 'C'");
    printf("%s, Address = %u", ptr, ptr);
    free(ptr);
    return 0;
}

재할당 실패 시 realloc()은 NULL 반환, 원본 블록은 유효한 상태 유지.

동적 배열(Dynamic Arrays)

동적 배열은 실행 중 요소 수 증가 가능, 알고리즘과 자료구조에서 흔한 패턴:

#include <stdio.h>
int main() {
    int *arr_dynamic = NULL;
    int elements = 2, i;
    arr_dynamic = calloc(elements, sizeof(int));
    for (i = 0; i < elements; i++) arr_dynamic[i] = i;
    for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]);
    elements = 4;
    arr_dynamic = realloc(arr_dynamic, elements * sizeof(int));
    printf("After realloc\n");
    for (i = 2; i < elements; i++) arr_dynamic[i] = i;
    for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]);
    free(arr_dynamic);
}

결과:

arr_dynamic[0]=0
arr_dynamic[1]=1
After realloc
arr_dynamic[0]=0
arr_dynamic[1]=1
arr_dynamic[2]=2
arr_dynamic[3]=3

요약

C 언어

  1. ROM, PROM, EPROM, EEPROM 이해: 설계, 프로그래밍, 식별
  2. C# 기초: 입출력(Essential Input/Output) 완벽 가이드
  3. C# using 문 마스터하기: 네임스페이스 임포트, 별칭, 정적 지시자
  4. C++ 메모리 관리 마스터: new와 delete 전문가 활용법
  5. C 사용자 정의 함수 4가지 검증된 패턴
  6. C 언어 동적 메모리 할당: malloc, calloc, realloc, free 마스터하기
  7. C 표준 라이브러리 함수 마스터하기: 실전 가이드
  8. C++ 동적 배열 할당 완벽 가이드: new, delete, 실전 코드 예제
  9. C++ 함수 완전 정복: 실전 코드 예제로 이해하기
  10. C 함수 마스터: 선언, 정의, 호출, 인자 전달(값/참조), 재귀