nullvuild

Bloger @nullvuild

Created Date '2025/03/24 오후 02:40

Modified Date '2025/03/24 오후 02:56

#C언어 #동적 메모리 #메모리 #free

C언어는 정적(static) 메모리만 사용하는 언어가 아니다.

실행 중에 필요한 만큼 메모리를 직접 요청하고 해제할 수 있는 기능, 즉 동적 메모리 할당도 지원한다.

이를 통해 배열의 크기를 런타임에 정하거나, 메모리를 효율적으로 활용할 수 있게 된다.


1. 왜 동적 메모리가 필요한가?

보통 배열은 선언할 때 크기를 고정해야 한다.


int arr[10];  // 크기 10 고정

하지만 입력받은 값에 따라 배열 크기가 달라질 수 있다면..?

이럴 땐 미리 크기를 정할 수 없기 때문에 동적으로 메모리를 할당해야 한다.


동적할당이 꼭 정답은 아니다. 경우에 따라서 입력받을 사이즈를 제한하면서 시스템을 운영하는 것이, 오히려 안정적이고 적절할 수 있다.

2. malloc: 메모리 할당 함수

가장 기본적인 메모리 할당 함수는 malloc()이다.


int *arr = (int *)malloc(sizeof(int) * 5);

  • sizeof(int) → int 하나의 크기 (보통 4바이트)
  • * 5 → int 5개 공간 확보
  • malloc()은 void * 형이므로 형변환 필요

if (arr == NULL) {
    printf("메모리 할당 실패\n");
}

malloc()은 할당에 실패하면 NULL을 반환하므로 꼭 체크해야 한다.


3. calloc: 초기화된 메모리 할당


int *arr = (int *)calloc(5, sizeof(int));

  • calloc()은 malloc()과 달리 0으로 초기화된 메모리를 할당해준다.
  • 인자 순서: 요소 개수, 자료형 크기

속도 때문인지, 현업에서는 calloc보다는 malloc위주로 사용한다. 아무래도 초기화를 하면, 그만큼 처리하는 시간은 늘어난다.

4. realloc: 메모리 크기 재조정


arr = (int *)realloc(arr, sizeof(int) * 10);

  • realloc()은 이미 할당된 메모리 크기를 늘리거나 줄일 때 사용
  • 내부적으로 새 공간을 확보하고, 기존 데이터를 복사해줌

5. free: 메모리 해제

동적으로 할당한 메모리는 반드시 사용 후 해제해줘야 한다.


free(arr);

  • free()를 하지 않으면 프로그램이 종료돼도 메모리가 남아 있게 되고, 메모리 누수(leak) 발생 가능
  • free() 후에는 포인터를 NULL로 초기화하는 습관도 좋다

free(arr);
arr = NULL;

6. 간단 예제

int n;
printf("몇 개의 정수를 입력할까요? ");
scanf("%d", &n);

int *nums = (int *)malloc(sizeof(int) * n);

if (nums == NULL) {
    printf("메모리 할당 실패\n");
    return 1;
}

// 값 입력
for (int i = 0; i < n; i++) {
    printf("%d번째 정수 입력: ", i + 1);
    scanf("%d", &nums[i]);
}

// 출력
printf("입력된 값들: ");
for (int i = 0; i < n; i++) {
    printf("%d ", nums[i]);
}

free(nums);

이 예제는 사용자 입력을 기반으로 동적 배열을 만들고 처리한 뒤, 마지막에 free()로 메모리를 해제한다.

실무에서 굉장히 흔하게 쓰이는 패턴이다.


7. malloc vs calloc vs realloc 요약

함수역할
"malloc"초기화되지 않은 메모리 할당
"calloc"0으로 초기화된 메모리 할당
"realloc"이미 할당한 메모리의 크기 조절
"free"할당된 메모리 해제

8. 동적 메모리에서 주의할 점

  • malloc() 후 NULL 체크는 필수
  • free()를 꼭 해줘야 함
  • 할당 후 사용하지 않거나, 해제 후 다시 쓰면 미정의 동작(undefined behavior) 발생
  • 포인터 복사 시 얕은 복사 vs 깊은 복사 개념도 유의해야 함

코멘트

동적 메모리는 포인터와 함께 쓰이기 때문에 처음엔 어렵게 느껴질 수 있지만,

한 번 개념이 잡히면 메모리 효율과 유연한 프로그램 구조를 만들 수 있는 아주 강력한 도구가 된다.

Nullvuild

Nullvuild

@nullvuild

프로필