이전까지는 포인터에 변수의 메모리 주소를 저장하는 방식으로 포인터를 사용했다.
이번에는 포인터에 원하는 만큼 메모리 공간을 할당받아 사용하는 방법을 알아보자.

메모리를 할당받아 사용하는 방법은 위 패턴을 항상 지켜야 한다.
참고 동적 메모리 할당
원하는 시점에 원하는 만큼 메모리를 할당할 수 있다고 하여 동적 메모리 할당(dynamic memory allocation)이라 부른다.
메모리를 사용하려면 malloc(Memory ALLOCation) 함수로 사용할 메모리 공간을 확보해야 한다.
이때 필요한 메모리 크기는 바이트 단위로 지정한다.
주의 필수적인 메모리 해제
변수를 선언하게 되면 변수에 자동으로 메모리 주소가 할당되고, malloc 함수를 사용하여 포인터를 선언하게 되면 메모리를 할당하여 포인터에 그 주솟값을 저장한다.
이때, 이 둘(변수와 포인터) 사이에는 내부적으로 약간의 차이가 있다.
변수는 스택(stack)에 생성되고 malloc 함수는 힙(heap) 부분의 메모리를 사용한다.
🤔 스택과 힙의 큰 차이점은 무엇일까??
스택과 힙의 큰 차이점은 메모리 해제에 있다.
스택에 생성된 변수는 사용한 뒤 따로 처리를 해주지 않아도 되지만, malloc 함수를 사용하여 힙에서 할당한 메모리는 반드시 해제를 해주어야 한다.
해제할 때 사용하는 함수가 바로 free 함수이다.
int *ptr = malloc(sizeof(int));
free(ptr);
메모리 해제는 선택이 아닌 필수이다.
만약 메모리를 해제하지 않아 메모리 사용량이 계속 증가하는 경우도 존재하는데, 이러한 현상을 메모리 누수(memory leak)이라 부른다.
포인터에 malloc 함수를 사용해 메모리를 할당한 뒤 특정한 값을 할당할 때는, 포인터를 역참조한 뒤 포인터의 자료형 크기만큼 값을 할당할 수 있었다.
예를 들어 int형 포인터는 4바이트 크기만큼 값을 할당한다.
즉, 값을 할당할 크기가 정해져 있다.
하지만 memset(MEmory SET) 함수를 사용하면 메모리의 내용을 원하는 크기만큼 특정 값으로 설정할 수 있다.
이때 설정하는 크기는 바이트 단위이다.
memset 함수는 주로 다음과 같이 설정할 값을 0으로 지정하여 메모리의 내용을 모두 0으로 만들 때 사용한다.
int *ptr = malloc(sizeof(int));
memset(ptr, 0, sizeof(int));
free(ptr);
입력
#include <stdio.h>
int main()
{
int *ptr = NULL;
printf("%p", ptr);
return 0;
}
출력
00000000
NULL이 들어있는 포인터를 널 포인터라고 하며, 아무것도 가리키지 않는 상태를 뜻한다.
아무것도 가리키지 않기 때문에 필연적으로 역참조가 불가능하다.
🤔 널 포인터는 언제? 왜? 사용할까??
실무에서는 다음과 같이 포인터가 NULL인지 확인한 뒤 NULL이면 메모리를 할당하는 패턴을 주로 사용한다.
if (ptr == NULL)
{
ptr = malloc(1024);
}
출처 : 남재윤, ⌜C언어 코딩 도장⌟, 길벗, 2021