배열, 포인터, 동적 메모리 - 3
동적 메모리 할당
변수를 선언하는 대신 프로그램의 요청으로 메모리를 할당하는 방식
malloc 함수를 사용하며 이를 통해 동적 메모리 할당을 요청함
malloc 함수 사용 -> 요구하는 크기의 메모리 할당 -> 시작 주소를 반환(void * 타입)
포인터 변수 p를 선언한 후 해당 변수에 malloc 을 이용하여 40byte 의 배열을 요청한다.
malloc(40) 을 사용하면 void * 타입으로 리턴하기에 malloc 함수 앞에 (int *) 을 붙여 int 로 형변환 한다.
이후 변수 p는 배열처럼 사용이 가능하다.
포인터와 배열은 밀접한 관계로 이루어져 있기에 malloc 을 이용하여 배열로 사용이 가능하다.
동적 메모리로 할당받은 배열은 공간이 부족할 경우 더 큰 배열로 할당하여 공간을 늘릴 수 있다.
어디까지나 이론적으로 늘리는것이 가능하다는 거지 실제로 이미 선언된 배열의 크기를 늘릴 수 있다는 의미는 아니다.
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 문이 동작하는 과정에서 정상적으로 동작되는지를 확인하고자 추가하여 출력하였다.