Language/자료구조

[1] C review < 동적메모리 할당 >

Return 2021. 11. 15. 19:49

변수를 선언하는 대신 프로그램의 요청으로 메모리를 할당할 수 있다. 이것을 동적 메모리 할당이라고 부릅니다. 

malloc 함수를 호출하여 동적메모리할당을 요청하면 요구하는 크기의 메모리를 할당하고 그 시작 주소를 반환합니다. 

malloc함수의 리턴값이 주소값이므로 당연히 포인터 변수를 사용해야 합니다. 

 

동적으로 할당된 배열은 공간이 부족할 경우 더 큰 배열을 할당하여 사용할 수 있습니다.

엄밀히 말하면 배열의 크기를 확장할 수 없습니다. 더큰 배열을 새롭게 만들어서 대체하는 방식으로 접근해야 합니다.

배열의 확장을 코드로 살펴봅시다. 

#include <stdio.h>
#include <string.h>

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

	//배열의 크기를 늘리는 방법 
	int* tmp = (int*)malloc(8 * sizeof(int));
	int i;
	for (i = 0; i < 4; i++)
		tmp[i] = array[i];

	array = tmp; // 새로운 주소값을 array에 대입
    
    array[4] = 4;
	array[5] = 5;

	printf("%d", array[5]);
	
}

======================================
5

 

사실 이 코드는 문제가 있습니다. 다시한번 위를 살펴보면 array의 배열을 확장시키기위해서 array배열보다 큰 tmp 배열을 새로 만들고 이 주소값을 다시 array의 주소값에 치환시켜 배열을 확장시켰습니다. 이때 원래 있던 array값이 허공에 둥 떠버리게 되는데 이를 가비지값이라고 합니다. 당장 프로그램에 문제를 끼치지는 않지만 이렇게 메모리상에 가비지값이 생기면 좋지는 않겠죠?

 

자 그럼 array[4]라고 배열을 선언하는 것과 동적 메모리 할당을 사용하여 int* array = (int*)malloc(4 * sizeof(int));라고 하는것은 어떤 차이가 있을까요 ?

 

바로 앞에서 우리는 배열의 이름은 배열의 시작 주소를 저장하는 포인터 변수이고 이값을 변경할 수 없다고 했습니다. 즉, array[4]라고 선언을 하면, 포인터 변수 값을 바꿀 수 없기 때문에 배열을 확장하거나 수정할 수 없습니다. 즉, 위의 코드가 오류가 뜰것입니다.