기본 콘텐츠로 건너뛰기

방송대 C프로그래밍 14강: 동적 메모리의 할당·확장·해제

0-썸네일-요약노트-C프로그래밍-14강

방송대 C프로그래밍 14강: 동적 메모리의 할당·확장·해제

입력 개수를 실행 전에 모른다면 배열을 몇 칸으로 선언해야 할까? 동적 메모리는 실행 중 필요한 크기만큼 힙에 공간을 요청하는 해법이지만, 주소를 잃거나 해제를 빠뜨리면 곧바로 누수와 잘못된 접근의 원인이 된다. 공간이 태어나고 커지고 반납되는 생애주기를 따라가며 각 함수의 역할과 실패 처리까지 점검해 보자.

배열 크기를 미리 정할 수 없는 순간에 문제가 시작된다

학생 점수를 최대 1,000개까지 받을 수 있다고 보고 int score[1000];을 선언하면 코드는 단순하다. 하지만 실제 입력이 8개라면 대부분의 공간을 쓰지 않는다. 반대로 100칸만 준비했는데 130개가 입력되면 배열 범위를 넘어갈 수 있다. 필요한 크기가 실행 중에야 정해지는 상황에서는 “최대치를 미리 예약”하는 방법만으로 유연성과 안전성을 함께 얻기 어렵다.

메모리 동적 할당은 프로그램 실행 중 필요한 크기를 계산하여 힙 영역에 공간을 요청하는 방식이다. 할당된 공간에는 일반 변수처럼 직접 사용할 이름이 없으므로 시작 주소를 포인터에 저장한다. 사용을 마치면 프로그래머가 free로 명시적으로 반납해야 한다.

동적 메모리의 기본 계약: 필요한 바이트 수를 계산해 주소를 요청하고, 반환값이 NULL인지 확인한 뒤, 유효한 범위 안에서 사용하고, 마지막에는 정확히 한 번 해제한다.

동적 할당은 “큰 배열을 만드는 문법”이 아니다. 크기 결정 시점을 컴파일 때에서 실행 중으로 옮기고, 그 대가로 주소와 수명을 직접 관리하는 방법이다.

데이터·스택·힙은 생성 시점과 소멸 책임이 다르다

프로그램 실행에는 기계어 코드가 저장되는 공간과 데이터가 저장되는 공간이 필요하다. 데이터 저장 공간은 대표적으로 데이터 영역, 스택 영역, 힙 영역으로 나뉜다. 이 구분은 단순한 위치 암기가 아니라 “언제 만들어지고 언제 사라지는가”를 판단하는 기준이다.

영역대표 대상생성·소멸 시점관리 책임
데이터 영역전역변수, 정적변수, 문자열 상수프로그램 시작부터 종료까지 유지프로그램 실행 흐름에 따라 관리
스택 영역함수의 지역변수와 매개변수함수 호출 때 생성되고 복귀 때 소멸호출과 복귀에 따라 자동 관리
힙 영역동적으로 요청한 기억공간할당 함수 호출 때 생성되고 free 때 반납프로그래머가 주소와 해제를 관리

전역변수는 프로그램이 실행되는 동안 계속 존재한다. 함수가 호출되면 그 함수의 매개변수와 일반 지역변수가 스택에 생기고, 함수에서 복귀하면 그 호출에 속한 변수는 사라진다. 반면 함수 안에서 힙 공간을 할당했다고 해서 함수 복귀 때 자동으로 해제되지는 않는다.

포인터 변수의 수명과 가리키는 공간의 수명은 별개다

void make_space(void) {
    int *p = malloc(sizeof *p);
    /* p는 스택의 지역변수, *p가 놓인 공간은 힙에 있다. */
}

함수가 끝나면 지역 포인터 p는 스택에서 소멸한다. 그러나 free(p)를 하지 않았다면 힙 공간은 반납되지 않는다. 그 공간의 주소를 저장한 유일한 포인터까지 사라졌으므로 다시 해제하기도 어려워진다. 이것이 메모리 누수로 이어지는 전형적인 경로다.

정적 할당과 동적 할당은 크기를 결정하는 시점으로 고른다

정적 할당은 프로그램을 작성할 때 필요한 크기를 정할 수 있는 변수, 배열, 구조체 등에 적합하다. 컴파일 과정에서 공간의 크기가 정해지고, 전역·정적 변수는 데이터 영역에, 함수의 일반 지역변수와 매개변수는 주로 스택 영역에 놓인다. 할당과 해제 흐름이 자동이므로 관리가 단순하고 오류 가능성이 낮다.

하지만 필요한 양을 미리 알아야 하며, 가장 큰 경우에 맞춰 배열을 선언하면 사용하지 않는 공간이 생길 수 있다. 동적 할당은 실행 중 입력된 개수에 맞춰 공간을 정할 수 있어 유연하지만, 실패 검사와 해제를 직접 책임져야 한다.

판단 질문정적 할당이 알맞은 경우동적 할당이 알맞은 경우
크기를 언제 아는가?작성·컴파일 단계에서 확정실행 중 입력이나 계산으로 결정
수명을 누가 끝내는가?범위와 프로그램 흐름이 자동 결정프로그래머가 free로 반납
크기가 바뀌는가?선언 뒤 고정realloc으로 변경 가능
핵심 위험은 무엇인가?최대치 예약에 따른 낭비할당 실패, 누수, 해제 후 접근

크기가 작고 고정된 지역 자료까지 무조건 힙에 두는 것이 좋은 설계는 아니다. 동적 할당은 실행 중 크기 결정이나 수명 제어가 실제로 필요할 때 선택해야 관리 비용에 이유가 생긴다.

malloc은 바이트 수를 받고 초기화되지 않은 공간을 돌려준다

malloc은 <stdlib.h>에 선언되어 있으며, 요청한 바이트 수만큼 힙 공간을 확보한 뒤 시작 주소를 void *로 반환한다. 할당에 실패하면 NULL을 반환한다. C에서는 이 반환값을 대상 포인터형으로 명시적으로 형변환하지 않아도 된다.

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int count = 5;
    int *score = malloc(sizeof *score * count);

    if (score == NULL) {
        puts("메모리 할당 실패");
        return 1;
    }

    for (int i = 0; i < count; i++) {
        score[i] = (i + 1) * 10;
    }
    printf("마지막 점수: %d\n", score[4]);

    free(score);
    score = NULL;
    return 0;
}

sizeof *score는 score가 가리킬 요소 하나의 크기를 구한다. 여기에 요소 수 5를 곱해 다섯 정수를 담을 바이트 수를 만든다. 할당 성공을 확인한 뒤 0번부터 4번 요소를 초기화하므로 마지막 출력은 50이다.

할당 직후의 값을 읽어서는 안 된다

malloc이 확보한 공간의 내용은 초기화되지 않은 상태다. 성공했다는 것은 주소 범위를 사용할 수 있다는 뜻이지, 그 안의 정수 값이 0이라는 뜻이 아니다. 각 요소에 값을 저장한 뒤 읽거나, 처음부터 0으로 채워진 공간이 필요하면 calloc을 선택한다.

바이트 계산 장치: “요소 하나의 크기 × 요소 개수”를 먼저 적고 그 결과를 할당 함수에 전달한다. 포인터형을 바꾸더라도 sizeof *pointer 표현은 요소형과 함께 바뀌어 크기 불일치 가능성을 줄인다.

calloc은 개수와 요소 크기를 나누어 받고 0으로 채운다

calloc은 요소 개수와 요소 하나의 크기를 별도 인수로 받는다. 성공하면 요청한 전체 공간의 바이트를 0으로 초기화하고 시작 주소를 반환하며, 실패하면 NULL을 반환한다.

int count = 5;
int *visit = calloc(count, sizeof *visit);

if (visit == NULL) {
    puts("메모리 할당 실패");
    return 1;
}

for (int i = 0; i < count; i++) {
    printf("%d ", visit[i]);
}
free(visit);

강의의 정수 배열 예처럼 다섯 요소는 모두 0으로 출력된다. malloc(sizeof *visit * count)와 calloc(count, sizeof *visit)은 같은 총 바이트 수를 요청할 수 있지만 초기 상태가 다르다.

함수크기 전달 방식할당 직후 내용공통 확인
malloc전체 바이트 수 하나초기화되지 않음반환값의 NULL 여부
calloc요소 수와 요소 크기모든 바이트를 0으로 초기화반환값의 NULL 여부

“동적 할당이면 모두 0”이라는 판단은 틀리다. 어떤 할당 함수를 사용했는지 확인해야 한다. 또한 calloc이 초기화해 주더라도 필요한 요소 수를 벗어난 인덱스까지 안전하게 만드는 것은 아니다.

realloc은 주소가 바뀔 수 있으므로 임시 포인터로 결과를 받는다

realloc은 이미 할당된 공간의 크기를 바꿀 때 사용한다. 더 큰 공간이 필요할 때 기존 위치 뒤가 비어 있으면 그 자리에서 확장될 수 있고, 그렇지 않으면 다른 위치를 확보해 기존 내용을 옮길 수 있다. 따라서 성공 후의 주소가 이전 주소와 같다고 가정해서는 안 된다.

int old_count = 5;
int new_count = 10;
int *score = malloc(sizeof *score * old_count);

if (score == NULL) {
    return 1;
}

int *temp = realloc(score, sizeof *score * new_count);
if (temp == NULL) {
    free(score);
    return 1;
}
score = temp;

먼저 새 크기를 요청하고 결과를 temp에 받는다. 실패하면 temp만 NULL이 되고 기존 score 공간은 여전히 유효하다. 예제는 더 진행할 수 없으므로 그 기존 공간을 해제하고 종료한다. 성공하면 temp가 유효한 새 시작 주소이므로 score = temp로 관리 포인터를 갱신한다.

왜 score = realloc(score, ...)이 위험할까

직접 대입한 호출이 실패하면 score에 NULL이 저장되어 기존 공간의 주소를 잃는다. 기존 공간 자체는 유지되므로 해제할 방법이 사라져 누수가 발생할 수 있다. 임시 포인터는 성공과 실패가 갈라지는 동안 기존 주소를 보존하는 안전장치다.

확장에 성공해도 새로 늘어난 부분이 자동으로 0이 되는 것은 아니다. 기존 크기 안의 내용은 보존되지만 추가된 요소는 사용 전에 직접 초기화해야 한다.

크기 변경의 두 갈래: 성공하면 새 주소를 채택하고 추가 영역을 초기화한다. 실패하면 기존 주소와 내용이 유지되므로 계속 사용할지 해제하고 종료할지 결정한다.

free는 공간을 반납하지만 포인터 변수까지 지우지는 않는다

free(p)는 p가 가리키는 동적 할당 공간을 힙에 반납한다. 그러나 포인터 변수 p 자체는 남아 있을 수 있고, 그 안에는 이전 주소 값이 그대로 들어 있다. 이 주소를 다시 참조하면 이미 해제된 공간을 사용하는 댕글링 포인터 오류가 된다.

free(score);
score = NULL;

해제 직후 NULL을 저장하면 포인터가 더 이상 유효한 객체를 가리키지 않는다는 상태가 코드에 드러난다. free(NULL)은 아무 작업도 하지 않으므로 조건에 따라 여러 경로에서 정리할 때도 도움이 된다. 다만 다른 포인터도 같은 공간을 가리키고 있었다면 그 별칭까지 자동으로 NULL이 되지는 않는다.

잘못된 상태발생 과정예방 기준
메모리 누수주소를 잃거나 해제를 빠뜨림모든 성공한 할당에 대응하는 반납 경로를 둠
댕글링 포인터해제된 주소를 계속 보관·참조해제 후 더 쓰지 않고 유지되는 포인터는 NULL로 갱신
이중 해제같은 할당 공간을 두 번 free소유권과 해제 여부를 한곳에서 관리
범위 초과요청한 바이트 밖을 읽거나 씀요소 수와 현재 용량을 포인터와 함께 추적

동적 메모리를 관리한다는 것은 포인터 하나만 저장하는 일이 아니다. 그 포인터가 가리키는 공간의 현재 크기, 초기화된 범위, 반납 여부를 함께 기록해야 한다.

메모리 함수는 비교·복사·채우기라는 목적부터 고른다

<string.h>에는 메모리 영역을 바이트 단위로 처리하는 함수가 있다. 세 함수는 모두 시작 주소와 바이트 수를 사용하지만 수행하는 작업은 다르다.

목적함수핵심 결과주의점
두 영역 비교memcmp(a, b, n)같으면 0, 앞이 작으면 음수, 크면 양수반환값의 부호를 사용하며 정확히 -1이나 1이라고 가정하지 않음
한 영역을 다른 곳에 복사memcpy(dest, src, n)src의 n바이트를 dest로 복사두 영역이 겹치면 안전하지 않으므로 memmove 사용
한 값으로 채우기memset(dest, c, n)dest의 n바이트를 지정한 바이트 값으로 채움자료형 요소가 아니라 바이트 단위

memcmp는 첫 번째 다른 바이트에서 방향을 정한다

char a[] = "aaa";
char b[] = "bbb";
int result = memcmp(a, b, 3);

if (result < 0) {
    puts("a 영역이 b 영역보다 작다");
}

첫 바이트 'a'가 'b'보다 작으므로 결과는 음수다. 강의 실행 화면에서는 -1이 보이지만, 판단에는 정확한 수치가 아니라 음수·0·양수라는 부호를 사용해야 한다.

memcpy와 memset은 널 문자보다 지정한 바이트 수를 따른다

char src[] = "1234567890";
char dest[] = "abcdefghijklmnopqrstuvwxyz";

memcpy(dest, src, 10);
memset(dest, '*', 4);

첫 호출은 src의 앞 10바이트를 dest의 앞 10바이트에 덮어쓴다. 문자열 끝의 널 문자는 복사 바이트 수 10에 포함되지 않으므로 뒤의 기존 문자들은 남는다. 이어지는 memset은 앞 네 바이트를 '*'로 바꾼다. 두 함수 모두 목적지의 실제 공간보다 큰 n을 주면 범위를 벗어나므로, 시작 주소와 바이트 수를 한 쌍으로 검토해야 한다.

가변 점수표는 용량 장부를 갱신하며 확장한다

동적 메모리의 전체 흐름을 하나의 점수표에 적용해 보자. 현재 요소 수 count와 확보한 칸 수 capacity를 구분한다. 새 점수가 들어왔는데 두 값이 같다면 빈 칸이 없으므로 용량을 늘린다.

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int count = 0;
    int capacity = 2;
    int input[] = {80, 95, 70, 88, 100};
    int *scores = malloc(sizeof *scores * capacity);

    if (scores == NULL) {
        return 1;
    }

    for (int i = 0; i < 5; i++) {
        if (count == capacity) {
            int new_capacity = capacity * 2;
            int *temp = realloc(scores,
                                sizeof *scores * new_capacity);
            if (temp == NULL) {
                free(scores);
                return 1;
            }
            scores = temp;
            capacity = new_capacity;
        }
        scores[count] = input[i];
        count++;
    }

    printf("개수=%d, 용량=%d, 마지막=%d\n",
           count, capacity, scores[count - 1]);
    free(scores);
    scores = NULL;
    return 0;
}

처음 용량은 2다. 세 번째 값을 넣기 전에 count==capacity가 되어 용량을 4로 늘리고, 다섯 번째 값을 넣기 전에 다시 8로 늘린다. 다섯 값을 저장한 뒤 count는 5, capacity는 8, 마지막 값은 100이므로 개수=5, 용량=8, 마지막=100이 출력된다.

  1. 요청: 요소 크기와 초기 용량을 곱해 malloc에 전달한다.
  2. 검사: 반환 주소가 NULL이면 사용하지 않고 실패 경로로 간다.
  3. 사용: count < capacity인 범위에서만 새 값을 저장한다.
  4. 확장: 임시 포인터로 realloc 결과를 받아 성공할 때만 주소와 용량을 갱신한다.
  5. 반납: 모든 정상·오류 종료 경로에서 소유한 공간을 한 번 해제한다.

메모리 장부: 포인터는 “어디인가”, count는 “몇 칸에 유효한 값이 있는가”, capacity는 “몇 칸까지 접근할 수 있는가”를 기록한다. 셋 중 하나라도 놓치면 주소는 있어도 안전한 범위를 판단할 수 없다.

핵심 개념 정리

  • 데이터 영역은 프로그램 전체 수명, 스택은 함수 호출 수명, 힙은 할당부터 명시적 해제까지의 수명을 가진다.
  • 정적 할당은 크기가 미리 정해질 때 단순하고 안정적이며, 동적 할당은 실행 중 크기를 결정해야 할 때 유연하다.
  • malloc은 전체 바이트 수를 받아 초기화되지 않은 공간을, calloc은 개수와 요소 크기를 받아 0으로 채운 공간을 요청한다.
  • 모든 할당 함수의 결과는 NULL인지 먼저 확인하고, 요소 크기·개수·현재 용량을 함께 추적한다.
  • realloc은 공간을 옮길 수 있고 실패해도 기존 공간을 유지하므로 임시 포인터로 결과를 받아야 한다.
  • free는 힙 공간을 반납하지만 포인터 변수는 남으므로, 유지되는 포인터는 해제 후 NULL로 갱신한다.
  • memcmp, memcpy, memset은 각각 비교·복사·채우기를 바이트 단위로 수행하며 지정 범위를 넘지 않아야 한다.

동적 메모리 문제는 함수 이름부터 외우지 말고 공간의 생애주기를 그린다. 크기를 요소 수와 바이트 수로 계산하고, 반환 주소를 검사한 뒤, 포인터·유효 요소 수·용량을 하나의 장부로 관리한다. 크기 변경은 기존 주소를 보존한 채 성공 여부를 나누고, 마지막에는 모든 종료 경로의 해제를 확인한다. 메모리 처리 함수까지도 “어디서 시작해 몇 바이트를 무엇과 비교·복사·채우는가”로 읽으면 같은 원리로 범위 오류를 막을 수 있다.

예상문제 10선

1. 메모리 동적 할당에 대한 설명으로 가장 알맞은 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④

  • ① 오답: 동적 할당은 컴파일 단계의 지역변수 초기화가 아니라 실행 중 힙 공간을 확보하는 일이다.
  • ② 오답: 스택의 지역변수는 호출과 복귀에 따라 자동 관리되며 동적 할당 대상은 힙이다.
  • ③ 오답: 전역변수의 자료형 변경이 아니라 이름 없는 힙 공간의 크기를 실행 중 정한다.
  • ④ 정답: 실행 시점에 크기를 정해 공간을 할당하고 반환된 시작 주소와 수명을 직접 관리한다.

2. 메모리 영역과 수명의 연결로 옳은 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①

  • ① 정답: 함수의 매개변수와 일반 지역변수는 호출에 대응하는 스택 공간을 사용한다.
  • ② 오답: 지역 포인터가 사라져도 힙 공간은 free 전까지 자동 반납되지 않는다.
  • ③ 오답: 전역변수는 프로그램 시작부터 종료까지 데이터 영역에서 유지된다.
  • ④ 오답: free는 동적 할당된 힙 공간에 사용하며 데이터 영역은 프로그램 종료와 함께 정리된다.

3. 정수 12개를 담을 공간을 포인터 p의 대상형에 맞춰 요청하는 표현은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③

  • ① 오답: 12는 요소 수이며 정수 12개의 전체 바이트 수가 아니다.
  • ② 오답: sizeof p는 포인터 변수 자체의 크기라서 대상 정수 12개의 공간을 나타내지 않는다.
  • ③ 정답: 대상 요소 하나의 크기에 요소 수 12를 곱해 필요한 전체 바이트 수를 구한다.
  • ④ 오답: 요소 수는 크기에 더하는 것이 아니라 요소 하나의 크기와 곱해야 한다.

4. 동적 메모리를 사용하는 기본 순서로 가장 적절한 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②

  • ① 오답: 아직 할당하지 않은 공간을 먼저 해제할 수 없고 실패 검사는 사용 전에 해야 한다.
  • ② 정답: 주소를 받을 포인터와 바이트 수를 준비하고 성공을 확인한 뒤 사용·반납한다.
  • ③ 오답: 할당 전 값을 읽을 수 없으며 성공한 할당에는 대응하는 해제가 필요하다.
  • ④ 오답: 유효한 주소 확인 전 역참조, 실패 후 사용, 이중 해제는 모두 잘못된 수명 관리다.

5. malloc과 calloc의 차이를 올바르게 설명한 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②

  • ① 오답: 두 함수 모두 할당에 실패하면 NULL을 반환한다.
  • ② 정답: calloc(n, size)은 n개 요소의 공간을 요청하고 할당된 바이트를 0으로 채운다.
  • ③ 오답: 두 함수 모두 동적 할당 함수이며 요청한 공간은 힙에 마련된다.
  • ④ 오답: 어떤 함수로 성공적으로 동적 할당했든 사용을 마치면 free로 반납해야 한다.

6. p = realloc(p, new_size);를 임시 포인터 없이 사용했을 때의 핵심 위험은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④

  • ① 오답: 확장 과정에서 다른 위치로 옮겨질 수 있어 성공 후 새 주소를 사용해야 한다.
  • ② 오답: 실패하면 기존 할당 공간은 유지되며 이를 가리키는 원래 주소가 필요하다.
  • ③ 오답: 기존보다 작은 크기로 변경하는 것도 가능하다.
  • ④ 정답: 반환값을 직접 덮어쓰면 실패 때 기존 주소를 잃어 그 공간을 해제하지 못할 수 있다.

7. free(p); 뒤에도 포인터 변수 p를 계속 사용할 수 있는 범위에 둔다면 가장 적절한 다음 문장은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③

  • ① 오답: 해제된 공간을 역참조하여 쓰는 동작이므로 허용되지 않는다.
  • ② 오답: 같은 공간을 다시 해제하는 이중 해제 위험이 있다.
  • ③ 정답: 더 이상 유효한 공간을 가리키지 않는다는 상태를 명시해 댕글링 포인터 사용을 줄인다.
  • ④ 오답: 해제된 주소를 읽는 것도 잘못된 접근이다.

8. 초기 용량 2인 배열이 가득 찰 때마다 두 배로 확장된다. 값 5개를 모두 저장한 뒤 용량은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①

  • ① 정답: 세 번째 값을 넣기 전 2에서 4로, 다섯 번째 값을 넣기 전 4에서 8로 확장한다.
  • ② 오답: 5는 유효한 요소 수이며 확보한 전체 용량은 다음 두 배 값인 8이다.
  • ③ 오답: 두 칸씩 더하는 방식이 아니라 현재 용량을 두 배로 만든다.
  • ④ 오답: 요소 수 5를 두 배로 만드는 것이 아니라 가득 찬 시점의 용량 4를 두 배로 한다.

9. 메모리 관리 함수와 역할의 연결로 옳은 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③

  • ① 오답: memcmp는 비교 결과를 음수·0·양수인 정수로 반환한다.
  • ② 오답: 영역이 겹치면 memcpy가 안전하지 않으므로 memmove를 사용한다.
  • ③ 정답: memset(dest, c, n)은 dest에서 시작하는 n바이트를 지정한 바이트 값으로 채운다.
  • ④ 오답: 힙 공간 반납은 free의 역할이며 memset은 공간의 내용을 바꾼다.

10. 동적 배열 코드를 검토하는 사고 순서로 가장 적절한 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②

  • ① 오답: 유효한 주소와 범위 확인 전에 접근하고 해제도 빠뜨려 안전한 단계가 없다.
  • ② 정답: 요청 크기, 할당 성공, 사용 경계, 주소 보존, 반납을 생애주기 순서로 모두 점검한다.
  • ③ 오답: 초기화 필요에 따라 함수를 고르고, 모든 할당과 재할당에는 실패 검사가 필요하며 이중 해제는 금지된다.
  • ④ 오답: 포인터와 함께 유효 요소 수와 용량을 기록하고 확장된 영역은 사용 전에 초기화해야 한다.

참고 자료와 작성 기준

이 글은 해당 차시 강의자료를 바탕으로 학습 목적에 맞게 재구성한 비공식 학습자료입니다. 동적 배열의 메모리 장부, 할당 실패 분기, realloc 주소 보존 절차, 비교·복사·채우기 함수의 선택표는 학습자가 메모리 생애주기와 범위를 직접 판독하도록 새로 구성했습니다.

  • 작성·편집: 올에이클래스 학습연구팀
  • 주요 근거: 한국방송통신대학교 컴퓨터과학과, 「C프로그래밍」 14강 메모리 동적 할당 강의자료, 2025
  • 보충 자료: 외부 자료를 사용하지 않음
  • 편집 원칙: 올에이클래스 편집 정책
  • 최종 내용 검토: 2026-09-07

댓글