자료구조

배열, 포인터, 동적 메모리 - 3

blesslee 2022. 11. 15. 16:29
반응형

동적 메모리 할당

 

변수를 선언하는 대신 프로그램의 요청으로 메모리를 할당하는 방식

malloc 함수를 사용하며 이를 통해 동적 메모리 할당을 요청함

 

malloc 함수 사용 -> 요구하는 크기의 메모리 할당 -> 시작 주소를 반환(void * 타입)

 

포인터 변수 p 에 malloc 을 사용하여 배열처럼 사용하는 예제

포인터 변수 p를 선언한 후 해당 변수에 malloc 을 이용하여 40byte 의 배열을 요청한다.

malloc(40) 을 사용하면 void * 타입으로 리턴하기에 malloc 함수 앞에 (int *) 을 붙여 int 로 형변환 한다.

이후 변수 p는 배열처럼 사용이 가능하다.

 

포인터와 배열은 밀접한 관계로 이루어져 있기에 malloc 을 이용하여 배열로 사용이 가능하다.

 

동적 메모리로 할당받은 배열은 공간이 부족할 경우 더 큰 배열로 할당하여 공간을 늘릴 수 있다.

어디까지나 이론적으로 늘리는것이 가능하다는 거지 실제로 이미 선언된 배열의 크기를 늘릴 수 있다는 의미는 아니다.

 

동적메모리 할당을 이용하여 array 배열의 크기를 증가시키는 과정

array (동적 메모리로 할당한 배열) 배열의 사이즈가 4면 충분하다고 생각하였는데,

실제 프로그램 동작과정에서 배열의 사이즈가 8이 필요할 경우 malloc 을 이용하여 array 배열을 8로 증가된 배열을 사용할 수 있도록  변경하는 과정이다.

 

앞서 배열 부분에서 배열의 포인터는 값을 변경할 수 없기 때문에 일반적인 배열로 선언하였을 경우에는 위와같은 방법을 사용할 수 없고, malloc 을 통해 선언한 배열만 이방법으로 증가된 배열로 바라보도록 변경이 가능하다.

 

//arr3.c 소스
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
        int * array = (int *)malloc(4*sizeof(int));
        array[0] = 1;
        array[1] = 2;
        array[2] = 3;

        printf("------- array init ------- \n");
        int * tmp = (int *)malloc(8*sizeof(int));
        int i;
        for (i=0; i<4; i++){
                tmp[i] = array[i];
                array[i] = 0;
                printf("%d \n", array[i]);
                }

        array = tmp;

        printf("------ array switch ------- \n");

        for (i=0; i<4; i++)
                printf("%d \n", array[i]);

        array[3] = 4;
        array[4] = 5;
        array[5] = 6;


        printf("------- add array ------- \n");

        for (i=0; i<8; i++)
                printf("%d \n", array[i]);

        return 0;
}
//arr3 실행결과
------- array init -------
0
0
0
0
------ array switch -------
1
2
3
0
------- add array -------
1
2
3
4
5
6
0
0

int * array = (int *)malloc(4*sizeof(int));

array[0] = 1;
array[1] = 2;
array[2] = 3;

위와같이 선언된 동적메모리 할당된 array[4] 의 배열에 각각 1, 2, 3 이라는 값을 입력 후,

 

int * tmp = (int *)malloc(8*sizeof(int));

 

tmp[8]을 동적메모리 할당으로 생성 이후  for 문을 통해 tmp 에 array 의 값들을 저장하였다.

 

array = tmp;

 

해당 구문을 통해서 array 가 가리키는 주소가 tmp 의 주소로 변경되도록 하였으며,

 

array[3] = 4;
array[4] = 5;
array[5] = 6;

 

array[4], array[5] 에 정상적으로 값이 입력되며 array 의 포인터가 8 사이즈의 배열을 바라보도록 변경되었다.

 

만약 위 예제에서 int * array = (int *)malloc(4*sizeof(int)); 가 아닌 int array[4]; 로 선언되었다면,

배열의 특성에 따라 array = tmp; 와 같은 주소값 변경이 불가능하여 다른 배열을 바라보도록 변경할 수 없다.

 

위 예제에서 기본적인 기능만을 테스트 하기 위해서라면 

 

array[i] = 0;

 

와 같은 array 배열을 0으로 초기화하는 과정은 필요없다.

다만 for 문이 동작하는 과정에서 정상적으로 동작되는지를 확인하고자 추가하여 출력하였다.

 

 

반응형