easy software

C언어 메모리의 동적할당을 이용하여 배열길이를 늘려보자 본문

C언어/메모리 관리와 동적 할당

C언어 메모리의 동적할당을 이용하여 배열길이를 늘려보자

JAVA 웹개발자 2015. 2. 13. 22:43

제목에서는 메모리의 동적할당을 이용하여 배열길이를 늘려보자라고 했는데,

 

배열의 길이를 늘린다기 보다는? 기존의 배열보다

 

길이가 더 긴 배열을 하나 만들어서 복사하는 형식으로 진행하려 합니다.

 

사실 이미 할당된 힙 메모리의 바이트를 증가시키는 함수는 정의되어 있습니다.

 

realloc이란 함수인데요, 이 함수를 사용하지 않고 예제를 해보려 합니다.

 

제 블로그의 메모리 관리와 동적 할당 부분을 보시면 기본 개념을 공부하실 수 있습니다.

 

이번 글에서는 예제를 진행합니다. 참고해주세요.

 

 

 

프로그램의 조건입니다.

 

1. 사용자로부터 -1을 입력받기 전까지 계속 정수를 입력받는다.

 

2. 초기 배열의 크기는 5로 설정하되, 사용자가 계속입력하면 길이를 3씩 증가시킨다.

 

3. 길이를 증가시킬 때, 새로운 배열을 하나 만들어서 증가시킨다.

 

4. 동적할당(malloc함수)을 이용한다.

 

 

전 이 문제를 풀면서, 상당히 까다로운 문제라고 생각했습니다.

 

포인터의 개념도 중요하고, C언어의 기본 개념도 상당히 많이 함축된 예제입니다.

 

애도 많이 먹었습니다.

 

 

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

 

void add(int*, int**);

 

int main(void){
     int size = 5;
     int* arr = (int*)malloc(sizeof(int)*size); //길이가 5인 배열 생성
     int i = 0;

 

     //-1이 입력될 때 까지 무한루프
     while (1){
          printf("정수를 입력하세요 : ");
          scanf("%d", &arr[i]);

 

          //사용자 입력값이 -1이면 반복문 탈출
          if (arr[i] == -1)
               break;

          //i+1번째가 size와 같으면 add함수를 호출
          if (i + 1 == size)
           add(&size, &arr);

 

          i++;
     }

 

     for (int j = 0; j < i; j++)
          printf("%d 인덱스의 값 : %d\n", j, arr[j]);

 

     free(arr);

     return 0;
}

 

//배열의 크기를 증가시키는 함수
void add(int* s, int** ar){
     int newsize = *s + 3; //size의 크기를 3 증가시킴

     //main의 arr보다 길이가 3긴 배열 생성
     int* temp = (int*)malloc(sizeof(int)*newsize);

 

     //ar의 값을 temp에 복사
     for (int i = 0; i < *s; i++)
          temp[i] = (*ar)[i];

 

     free(*ar); //이전 배열 삭제

     *ar = temp;
     *s += 3; //main의 size를 3증가시킴
}

 

 

처음에 malloc을 이용한 동적할당을 통해 길이가 5인 배열을 생성합니다.

 

그리고 배열의 인덱스+1이 size인 5가되면, 즉 사용자가 5번을 입력하면 add함수를 호출합니다.

 

add함수를 호출할때 인자로 포인터의 주소값을 전달했으므로,

 

함수의 매개변수는 더블 포인터이어야 합니다.

 

후에 동적할당을 통해 길이가 main의 arr함수보다 3이 긴 temp함수를 생성합니다.

 

그리고 arr의 값을 temp에 복사합니다.

 

복사가 완료되면 free함수를 통해 이전 배열을 삭제해줍니다.

 

그리고 *s += 3 을 통해 main의 size를 3 증가시켜서, 사용자로부터 3개의 값을 더 입력받도록 합니다.

 

 

 

동적할당을 해주었다면, 항상 free함수를 통해 힙 영역의 할당된 메모리를 소멸시켜야 합니다.

 

위의 예제는 여러분들이 문제만 보고 따로 작성해보면 좋겠지만,

 

코드를 보고 이해하고 그림을 그려봄으로써 동적할당을 이해하시는게 좋을 것 같습니다.

 

만약에 그래도 잘 이해가 되지 않는다면, 아래의 그림을 보고 이해해주세요.

 

 

 

사용자가 6개를 입력해서 add함수가 한번 호출되었을 경우(중요한 변수만 그렸습니다.)

 

 

 

 

 

 

 

 

size는 처음에 5였으나, add함수가 호출되고나면 8이 됩니다.

 

그리고 arr의 주소값을 add함수에게 주었기 때문에 ar이 arr을 가리킵니다.

 

힙 영역의 5칸 짜리 배열을 free함수로 소멸시키고 temp가 가리키고있는 8칸짜리 배열을

 

*ar이 가리키게 합니다. 즉 arr이 temp가 가리키는 배열을 가리키게 됩니다.

 

 

 

 

사용자가 9개를 입력해서 add함수가 두번 호출되었을 경우(중요한 변수만 그렸습니다.)

 

 

 

 

 

add함수를 한번 호출했을 때와 크게 다르지 않습니다.

 

size는 11이 되었고, temp는 새로운 11칸짜리 배열을 가리킵니다.

 

원래는 8칸 짜리 배열을 계속 가리키고 있었는데, malloc함수를 통해 새로운 메모리를 할당받으면서

 

그 메모리를 temp가 가리키게 되는 것입니다.

 

이후에 배열을 *ar이 가리키게 함으로써, arr이 temp가 가리키는 배열을 가리킵니다.

 

이렇게 배열의 이름을 바꾸지 않으면서 크기만 늘려갈 수 있다는 것이 참으로 놀랍네요.

 

add함수를 백번 호출해도 이 개념에서 벗어나는 것은 1%도 없습니다.

Comments