본문 바로가기

Programming/C

C 언어 | 배열의 크기 조정하기

학습 목표

배열의 크기를 조정하는 코드를 작성할 수 있다.

 

컴퓨터 안의 메모리는 마치 사물함과 같다. 한 번 사물함의 개수를 정한 이후에는 공간이 모자란다고 해서 주변의 사물함을 마음대로 더 사용할 수 없다. 배열을 정의할 때도 마찬가지다. 이미 일정한 크기가 할당되어 있는 상황에서 그 크기를 늘리는 일은 단순하지 않다.

 

배열의 크기 조정하기

1. for 루프를 사용해 값 복사

배열의 크기를 키워야 한다면 어떻게 해야 할까. 배열이 저장된 메모리 위치 옆에 메모리를 덧붙이자 생각할 수 있지만, 그곳에는 다른 데이터가 저장돼 있을 수 있다.

 

따라서 안전하게 배열의 크기를 키우기 위해서는 새로운 공간에 큰 크기의 메모리를 다시 할당하고 배열의 값을 하나씩 옮겨줘야 한다. 이 과정은 배열의 크기(n)만큼 시간이 소요되기 때문에 시간 복잡도는 O(n)이다.

 

과정을 코드로 표현하면 다음과 같다.

 

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

int main(void){
    // list 포인터를 선언하고 int 자료형 3개 만큼의 메모리 할당
    int *list = malloc(3 * sizeof(int));
    
    // 포인터가 제대로 선언되었는지 확인
    if(list == NULL){
        return 1;
    }
    
    // list 배열의 각 인덱스에 값 저장
    list[0] = 1;
    list[1] = 2;
    list[2] = 3;
    
    // 배열의 크기를 늘리고 싶은 상황
    // 더 큰 크기의 포인터 tmp를 선언하고 메모리 할당
    int *tmp = malloc(4 * sizeof(int));
    
    if(tmp == NULL){
        return 1;
    }
    
    // list의 값을 tmp로 복사
    for(int i = 0; i < 3; i++){
        tmp[i] = list[i];
    }
    
    // tmp 배열의 네 번째 값 저장
    tmp[3] = 4;
    
    // list 메모리 초기화
    free(list);
    
    //tmp가 list를 가리키도록 지정
    list = tmp;
    
    // list 값 확인
    for(int i = 0; i < 4; i++){
        printf("%i\n", list[i]);
    }
    
    // list 메모리 초기화
    free(list);
}

 

프로그램을 실행시켜보자.

 

 

tmp의 값이 list로 잘 복사되었다. 

 

 

free 함수를 사용해 list의 메모리를 해제시켰기 때문에 메모리 누수를 검사했을 때에도 에러가 없는 것을 확인할 수 있었다.

* 메모리 누수 확인 프로그램으로는 valgrind를 사용한다(명령 프롬프트에 valgrind 파일명 입력).

 

2. realloc 함수 사용

위 과정을 realloc 함수를 사용해서 좀 더 간단하게 구현해보자.

 

  • realloc 함수는 이전에 할당된 메모리 크기를 조절하는 함수이다.
  • 크기는 이전 메모리보다 작거나 크게 할당할 수 있다.
  • 메모리에 저장된 데이터를 그대로 복사할 수 있다.
  • 헤더 파일은 malloc 함수와 동일하게 <stdlib.h>를 사용한다.

 

syntax는 다음과 같다.

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

 

코드를 보자.

 

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

int main(void){
    int *list = malloc(3 * sizeof(int));
    
    if(list == NULL){
        return 1;
    }
    
    list[0] = 1;
    list[1] = 2;
    list[2] = 3;
    
    int *tmp = realloc(list, 4 * sizeof(int));
    
    if(tmp == NULL){
        return 1;
    }
    
    list = tmp;
    
    list[3] = 4;
    
    for(int i = 0; i < 4; i++){
        printf("%i\n", list[i]);
    }
    
    free(list);
}

 

realloc 함수로 tmp를 선언해 메모리 크기를 늘리고, 값을 복사했다.

 

실행 결과는 다음과 같다.

 

 

생각해보기

이미 할당된 메모리의 크기를 조절할 때 임시 메모리를 새로 할당해줘야 하는 이유는 무엇일까?

기존에 할당된 메모리의 주위에는 다른 데이터가 담겨 있을 수 있기 때문이다. 따라서 필요한 메모리만큼 임시 메모리를 새로 할당해줘야 한다.

 

 

realloc 함수 내용 출처

 

C Language: realloc function (Resize Memory Block)

C Language: realloc function(Resize Memory Block) In the C Programming Language, the realloc function is used to resize a block of memory that was previously allocated. The realloc function allocates a block of memory (which be can make it larger or smalle

www.techonthenet.com


이 글은 네이버 부스트 코스 David J. Malan(데이비드 J. 말란) 교수님의 모두를 위한 컴퓨터 과학(CS50 2019) 강의를 수강하고 작성한 글입니다. 본 강좌 내 실습에서는 CS50 Sandbox를 사용합니다.

 

 

모두를 위한 컴퓨터 과학 (CS50 2019)

부스트코스 무료 강의

www.boostcourse.org

'Programming > C' 카테고리의 다른 글

C 언어 | malloc과 포인터  (0) 2021.02.26
C 언어 | 파일 쓰기와 읽기  (0) 2021.02.22
C 언어 | 메모리 교환, 스택, 힙  (0) 2021.02.22
C 언어 | 메모리 할당과 해제  (0) 2021.02.22
C 언어 | 문자열의 복사  (0) 2021.02.20