realloc으로 확장하기
동적 배열의 크기를 조정해 보세요.
realloc으로 확장하기은(는) CoddyKit의 무료 C Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 C Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. C Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
malloc 하나로 충분하지 않을 때
배열을 할당하고 값을 채운 뒤 더 많은 공간이 필요하다는 것을 알게 되는 경우가 있습니다. 배열 끝을 넘어 바로 쓸 수는 없습니다.
realloc을 사용하면 기존 힙 블록의 크기를 조정하면서 이미 저장된 데이터를 유지할 수 있습니다.
realloc의 형식
realloc(ptr, new_bytes)는 기존 포인터와 새로운 전체 크기(바이트 단위)를 전달받습니다.
새 크기의 블록을 가리키는 포인터를 반환합니다. 기존 크기와 새 크기 중 더 작은 크기까지의 데이터는 보존됩니다.
int *bigger = realloc(a, new_n * sizeof(*a));블록이 이동할 수 있습니다
realloc은 블록을 현재 위치에서 확장할 수도 있고, 새 블록을 할당하여 데이터를 복사한 뒤 기존 블록을 해제할 수도 있습니다.
어느 경우든 기존 포인터가 더 이상 유효하지 않을 수 있습니다. 이후에는 반환된 포인터를 사용해야 합니다.
a = realloc(a, new_n * sizeof(*a));
/* the old value of a may no longer be valid */자기 대입의 함정
a = realloc(a, ...)처럼 작성하면 깔끔해 보이지만 위험합니다. realloc이 NULL을 반환하면 a를 덮어써서 기존 포인터를 잃고 기존 블록이 누수됩니다.
대신 임시 변수를 사용하십시오.
int *tmp = realloc(a, new_n * sizeof(*a));
if (tmp == NULL) { /* a is still valid */ return 1; }
a = tmp;배열을 안전하게 늘리기
이 프로그램은 정수 3개를 할당한 다음 realloc으로 6개까지 늘리며, 처음 세 값을 유지합니다.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *a = malloc(3 * sizeof(*a));
if (!a) return 1;
for (int i = 0; i < 3; i++) a[i] = i + 1;
int *tmp = realloc(a, 6 * sizeof(*a));
if (!tmp) { free(a); return 1; }
a = tmp;
for (int i = 3; i < 6; i++) a[i] = i + 1;
for (int i = 0; i < 6; i++) printf("%d\n", a[i]);
free(a);
return 0;
}새 바이트는 초기화되지 않습니다
블록을 늘리면 끝의 추가 공간에는 새로 할당된 malloc 메모리와 마찬가지로 쓰레기 값이 들어 있습니다.
realloc은 기존 데이터를 보존하지만 새 영역을 0으로 초기화하지는 않습니다. 읽기 전에 초기화하십시오.
a = realloc(a, 6 * sizeof(*a));
for (int i = 3; i < 6; i++) a[i] = 0; /* clear new slots */두 배로 늘리는 전략
요소 하나를 추가할 때마다 realloc을 호출하면 느립니다. 공간이 부족해질 때마다 용량을 두 배로 늘리는 것이 고전적인 방법입니다.
이 방법은 배열이 커지는 동안 재할당 횟수를 줄여 평균적으로 좋은 성능을 냅니다.
if (count == cap) {
cap = cap ? cap * 2 : 4;
int *tmp = realloc(a, cap * sizeof(*a));
if (!tmp) { free(a); return 1; }
a = tmp;
}요소를 추가하며 배열 만들기
이 프로그램은 빈 상태에서 시작하여 숫자를 추가하고, 필요할 때 용량을 두 배로 늘립니다.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *a = NULL;
size_t count = 0, cap = 0;
for (int v = 1; v <= 5; v++) {
if (count == cap) {
cap = cap ? cap * 2 : 2;
int *tmp = realloc(a, cap * sizeof(*a));
if (!tmp) { free(a); return 1; }
a = tmp;
}
a[count++] = v;
}
for (size_t i = 0; i < count; i++) printf("%d\n", a[i]);
free(a);
return 0;
}realloc(NULL, n)은 malloc처럼 동작합니다
포인터로 NULL을 전달하면 realloc은 정확히 malloc처럼 동작합니다.
따라서 두 배로 늘리는 반복문에서 a = NULL로 시작할 수 있습니다. 첫 번째 realloc이 초기 블록을 할당하기 때문입니다.
int *a = NULL;
a = realloc(a, 4 * sizeof(*a)); /* same as malloc(4 * sizeof(*a)) */블록 줄이기
realloc은 블록을 더 작게 만들 수도 있습니다. 새 크기까지의 데이터는 유지되고 나머지는 버려집니다.
크기를 줄이면 메모리를 운영 체제에 돌려줄 수 있지만, 구현에 따라 더 큰 블록을 그대로 유지할 수도 있습니다.
int *tmp = realloc(a, 2 * sizeof(*a)); /* down from more */
if (tmp) a = tmp;수학 연산에서 오버플로 방지
용량이 커지면 cap * sizeof(*a)가 size_t의 범위를 초과하여 아주 작은 값으로 되돌아갈 수 있습니다.
매우 큰 배열에서는 곱셈이 오버플로되지 않는지 확인하거나, 지원하는 시스템에서 reallocarray를 사용하십시오.
if (cap > SIZE_MAX / sizeof(*a)) { /* overflow */ return 1; }
int *tmp = realloc(a, cap * sizeof(*a));빠른 확인
realloc에 대한 이해도를 확인해 보십시오.
복습
realloc은 힙 블록의 크기를 조정하며 블록을 이동시킬 수도 있으므로, 항상 반환된 포인터를 사용하십시오.
실패해도 원래 블록이 누수되지 않도록 임시 변수에 대입하십시오. 속도를 위해 크기를 두 배씩 늘리고, 새 슬롯을 초기화하며, realloc(NULL, n)이 malloc과 같다는 점을 기억하십시오. 다음에는 이 로직을 재사용 가능한 벡터 형식으로 감싸 보겠습니다.
자주 묻는 질문
“realloc으로 확장하기” 강의는 무료인가요?
네 — “realloc으로 확장하기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 C Academy 강의 전체를 잠금 해제할 수 있습니다. C Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“realloc으로 확장하기”에서 뭘 배우나요?
동적 배열의 크기를 조정해 보세요. 브라우저에서 직접 실행하는 실습 코드로 C Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
C Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 C Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.
“realloc으로 확장하기” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 C Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 C Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 배열 할당하기
- realloc으로 확장하기
- 재사용 가능한 벡터 형식
- 해제하고 누수 방지하기