malloc 함수를 이용하여 heap영역에 메모리 공간을 할당하고, 할당된 메모리 공간은 free 함수의 호출을 통해서 해제한다.
이를 통해 함수가 매번 호출될 때마다 할당되고, 또 함수를 빠져나가도 유지가 되는 생성과 소멸의 시기가 지역변수나 전역변수와는 다른 유형의 변수를 만들 수 있다 !
Ex 1.
1. int main(void)
2. {
3. void * ptr1 = malloc(4);
4. void * ptr2 = malloc(12);
5. ...
6. free(ptr1);
7. free(ptr2);
8.
9. return 0;
10. }
line 3 : malloc 함수 호출, 4 전달 -> heap 영역에 4byte를 할당하고, 첫번째 byte의 주소값을 void형 포인터변수 ptr1에 반환한다.
line 4 : malloc 함수 호출, 12 전달 -> heap 영역에 12byte를 할당하고, 첫번째 byte의 주소값을 void형 포인터변수 ptr1에 반환한다.
line 6 : ptr1을 인자로 하는 free 함수를 호출하여 생성한 4byte짜리 메모리 공간을 해제한다.
line 7 : ptr2를 인자로 하는 free 함수를 호출하여 생성한 4byte짜리 메모리 공간을 해제한다.
void * ptr1 = malloc(4) -> *ptr1 = 20; // 포인터 연산 불가능!
int * ptr1 = (int*)malloc(sizeof(int)); -> *ptr1 = 20; // 포인터 연산 가능 !
malloc 함수의 일반적인 호출형태와 sizeof 연산 이후 실질적인 malloc의 호출을 보면 알 수 있다.
1) void * ptr1 = malloc(sizeof(int));
2) void * ptr2 = malloc(sizeof(double));
3) void * ptr3 = malloc(sizeof(int)*7;
4) void * ptr4 = malloc(sizeof(double)*9);
1) void * ptr1 = malloc(4);
2) void * ptr2 = malloc(8);
3) void * ptr3 = malloc(28);
4) void * ptr4 = malloc(72);
결국 전달받은 바이트크기만큼 메모리를 할당하는 malloc함수 입장에서는 sizeof 연산 후 실질적으로는 달랑 숫자정보밖에 전달받지 못한다. 때문에, 할당하는 메모리의 용도가 int형인지, float형인지, char형 배열인지 도무지 알 수가 없다.
그렇기 떄문에 어떤 주소값이든 담을 수 있는 void형 포인터로 반환한다.
malloc 함수는 원하는 크기만큼 heap영역에 메모리 공간을 할당하고, 그 메모리의 주소값(메모리의 첫 번째 byte의 주소값)을 void형 포인터로 반환한다.
따라서 프로그래머는 void형으로 반환되는 주소값을 원하는 type으로 적절히 형변환하여 할당된 메모리 공간에 접근해야 한다.
1) int * ptr1 = (int*)malloc(sizeof(int));
2) double * ptr2 = (double*)malloc(sizeof(double));
3) int * ptr3 = (int*)malloc(sizeof(int)*7);
4) double * ptr4 = (double*)malloc(sizeof(double)*9);