int arr[10];): 프로그램을 만들 때 크기를 10개로 고정합니다. 프로그램을 켜서 실행하는 도중에 11개로 크기를 늘릴 수 없습니다.typedef struct {
int *data; // 힙 메모리에 만든 배열의 시작 주소 번호 (8바이트)
size_t len; // 현재 배열에 실제로 들어있는 숫자 개수 (정수)
size_t cap; // 현재 할당받은 메모리에 최대 담을 수 있는 숫자 개수 (정수)
} IntList;
data: 숫자들이 저장된 힙 메모리의 시작 주소 번호입니다.len: 현재까지 사용자가 배열에 집어넣은 숫자의 개수입니다.cap (Capacity, 용량): 현재 운영체제로부터 받아둔 메모리에 숫자를 최대 몇 개까지 넣을 수 있는지를 적어둔 숫자입니다.IntList list;처럼 함수 안에서 만든 변수 자체가 자리 잡는 메모리 영역입니다. 함수가 끝나면 자동으로 사라집니다.malloc() 함수를 호출했을 때 운영체제가 따로 떼어주는 메모리 영역입니다. 사용자가 직접 해제하기 전까지 계속 유지됩니다.list는 스택에 있고, list.data 안에 적힌 주소가 가리키는 실제 숫자 공간들은 힙에 있습니다.static void list_push(IntList *l, int x) {
// 1단계: 현재 개수(len)와 최대 용량(cap)이 같은지 검사
if (l->len == l->cap) {
size_t newcap = l->cap * 2; // 용량을 2배로 계산 (예: 8개 -> 16개)
// 2단계: realloc으로 16개 * 4바이트(int 크기) = 64바이트 힙 메모리를 새로 확보
int *p = realloc(l->data, newcap * sizeof(int));
if (p == NULL) {
exit(1); // 메모리 부족 시 종료
}
l->data = p; // 새 주소로 변경
l->cap = newcap; // 최대 용량을 16으로 변경
}
// 3단계: 데이터를 넣고 개수를 1 증가시킴
l->data[l->len] = x;
l->len++;
}
이 오류는 변수에 적어둔 용량 숫자(cap)와 실제 힙에 빌려둔 물리 바이트 크기가 맞지 않을 때 일어납니다.
sizeof(int)(4바이트)를 곱하지 않고 realloc(l->data, 16)을 실행했다고 가정합니다.int 16개(64바이트)가 아니라, 오직 16바이트(int 4개 분량)만 힙에 할당합니다.l->cap = 16;이라고 적혀 있습니다.list_push 코드는 cap이 16이므로 5번째, 6번째, 7번째 숫자를 넣을 때도 공간이 충분하다고 판단하여 힙 메모리에 값을 씁니다.cap 변수 값은 실제 운영체제로부터 할당받은 int 개수와 반드시 일치해야 합니다.malloc이나 realloc을 호출할 때는 반드시 원소 개수에 데이터 1개의 크기(sizeof(int))를 곱한 총 바이트 수를 넘겨야 메모리 침범이 발생하지 않습니다.