방구석 컴퓨터/C,C++ / / 2021. 1. 13. 22:54

동적 메모리 할당[C]

반응형

프로그램에서 새로운 정보를 저장할 공간을 확보하기를 원할 때가 있다.

프로그램을 작성할 당시에는 얼마나 많은 공간이 필요한지 알 수도 없고 그렇다고 사용되지 않을지도 모르는 아주 큰 공간을 미리 할당해놓기는 부담스럽기 때문이다. 이러한 문제를 해결하기 위해 C 에서는 실행 중에 메모리 할당을 할 수 있도록 히프(heap)라는 기법을 제공한다.


위에서 말한 메모리 할당을 위해서는 malloc 이라는 함수를 호출하여 필요한 양의 공간을 요구할 수 있다.

malloc에 대한 MSDN 설명 : https://msdn.microsoft.com/ko-kr/library/6ewkz86d.aspx

malloc 함수를 사용했을 때, 요구한 공간의 크기를 사용할 수 있으면 메모리 영역에 있는 그 공간의 시작 주소에 대한 포인터를 반환해주고, 사용할 수 없으면 NULL 포인터가 반환된다.

나중에 메모리 영역이 더 이상 필요 없게 되면 free 라는 함수를 통해서 그 영역을 메모리에 다시 반환할 수 있다. 반환되면 그 영역에 있던 데이터는 그 프로그램에서 다시 사용할 수 없다.

밑에 예시 프로그램이 있다.

//프로그램1
int i, *pi;
float f, *pf;

pi = (int *)malloc(sizeof(int));
pf = (float *)malloc(sizeof(float));

*pi = 1024;
*pf = 3.14;

printf("an integer = %d, a float = %f\n", *pi, *pf);

free(pi);
free(pf);

위에 프로그램에서 보이듯이 malloc 함수 호출은 int 나 float 을 저장하는 데 필요한 저장 공간의 크기를 결정하는 매개변수를 포함한다. ex) sizeof(int), sizeof(float)

malloc 함수의 리턴값은 적절한 크기의 메모리 영역에 대한 첫 번째 주소를 가리키는 포인터이다.

그러나 이 결과의 타입은 시스템마다 다양하다. 위에 프로그램의 (int*) (float*)는 타입 변환식을 나타낸다. 이 타입 변환식은 결과 포인터를 적당한 타입의 포인터로 변환시키고, 이 포인터는 적절한 포인터 변수에 지정된다.

포인터가 대상체의 타입을 필요로 하는 이유

1. 대상체의 바이트수와 비트해석 방법을 알아야 하기 때문에.

2. 인접한 다른 대상체로 이동할 때 이동거리를 알기위해. ex) 증감연산자 ++로 이동할 때 int형 이라면 4 byte를 이동하고 float형 이라면 8 byte를 이동


malloc 함수를 사용할 때 메모리 부족으로 실패할 가능성이 있기 때문에 malloc 을 호출하는 코드 라인들을 밑의 코드와 같이 대체함으로써 보다 개선하여 사용할 수 있다.

if (!(pi = malloc(sizeof(int))) || (!(pf = malloc(sizeof(float))))
{
	fprintf(stderr, "Insufficient memory");
	exit(EXIT_FAILURE);
}

malloc은 프로그램의 여러 곳에서부터 호출되기 때문에 malloc을 기동시키고, malloc이 실패할 때 빠져나가는 매크로를 정의하는 것이 편리할 때가 있다. 이러한 매크로는 밑의 코드와 같이 정의할 수 있다.

#define MALLOC(p,s)
	if (!((p) = malloc(s))){
		fprintf(stderr, "Insufficient memory");
		exit(EXIT_FAILURE);
	}

이 매크로를 사용하면 가장 처음 봤던 프로그램1의 동적 할당 코드는 아래의 코드처럼 대체될 수 있다.

MALLOC(pi, sizeof(int));	//pi = (int *)malloc(sizeof(int));

MALLOC(pf, sizeof(float));	//pf = (float *)malloc(sizeof(float));

동적으로 할당된 저장 공간에 대한 모든 포인터가 없어지면 프로그램의 입장에서 볼 때 그 저장 공간도 없어지게 되는데 이것을 허상 참조라고 한다.

반응형

'방구석 컴퓨터 > C,C++' 카테고리의 다른 글

포인터의 위험성💀  (0) 2021.01.14
포인터[C]  (0) 2021.01.13
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유