C | 동적 메모리 malloc, calloc, realloc

성수당·2025년 8월 7일

C언어

목록 보기
3/4
post-thumbnail

🥔 왜 동적 메모리를 써야 할까?

정적 메모리(int arr[100])는 크기가 고정되어 있어 런타임 중에 크기를 바꿀 수 없다.
반면, 동적 메모리는 실행 중 필요한 만큼 메모리를 요청해서 사용하는 방식이다.

예를 들어 사용자 입력에 따라 배열 크기를 정하거나, 구조체 배열을 유동적으로 늘릴 때 필요하다.

🥔 malloc

void *malloc(size_t size);

  • 지정한 바이트 크기만큼 메모리를 할당하고, 그 주소를 반환한다.

  • 실패 시 NULL을 반환한다.

  • 반환된 메모리는 초기화되지 않는다 (쓰레기값 존재 가능).

예제

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

if (arr == NULL) {
    // 메모리 할당 실패 처리
}

arr[0] = 10;

| sizeof(type)을 이용해 정확한 바이트 수를 계산하는 것이 중요하다.

🥔 calloc

void *calloc(size_t n, size_t size);

  • n * size 바이트만큼 메모리를 할당하고, 모든 값을 0으로 초기화한다.

  • 내부적으로 malloc + memset과 유사한 동작을 한다.

예제

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

arr[0] == 0;  // 초기화된 값

| 구조체나 배열을 할당할 때 유용하다. 단, 초기화 비용이 있기 때문에 성능이 중요한 경우에는 malloc을 선호하기도 한다.

🥔 realloc

void *realloc(void *ptr, size_t new_size);

  • 이미 할당된 메모리 블록을 새로운 크기로 재할당한다.

  • 기존 내용은 유지된다.

  • 주소가 바뀔 수 있으므로 반환값으로 받은 새 포인터를 꼭 사용해야 한다.

예제

int *arr = (int *)malloc(3 * sizeof(int));
arr[0] = 1; arr[1] = 2; arr[2] = 3;

int *new_arr = (int *)realloc(arr, 6 * sizeof(int));

if (new_arr != NULL) {
    arr = new_arr;
    arr[3] = 4;
}

| realloc은 내부적으로 malloc → memcpy → free와 비슷하게 동작한다. 주소가 바뀔 수 있으므로, 반드시 새 포인터로 덮어써야 한다.

🥔 free

free(ptr);

  • malloc, calloc, realloc로 할당한 메모리를 해제한다.

  • 해제 후 해당 포인터를 다시 사용하면 안 된다(댕글링 포인터 위험).

int *p = malloc(10);
free(p);
p = NULL;  // 이 처리가 안전

🥔 정리

함수역할초기화 여부사이즈 인자주의점
malloc메모리 할당1개 (바이트 수)쓰레기값
calloc메모리 할당2개 (갯수, 크기)느릴 수 있음
realloc크기 재조정유지새 크기주소 바뀔 수 있음
free메모리 해제해당 없음없음해제 후 NULL 처리 권장

🥔 메모리 누수 주의

동적 할당은 직접 관리해야 하기 때문에, 할당 후 반드시 해제해야 한다.
해제하지 않으면 메모리 누수가 발생하고, 반복되면 시스템 리소스를 잡아먹는다.

| valgrind 같은 도구로 메모리 누수를 확인할 수 있다.

profile
말하는 감자🥔

0개의 댓글