동적할당
동적할당
RAM의 메모리를 쓰는 경우가 2가지가 있다고 했다. 변수와 동적할당이 이 2가지다. 그리고 메모리를 쓰고 받는 데는 3가지 과정이 있었다. 요구, 사용, 반환이 이 3가지다. 이것을 변수는 요구와 반환이 자동인데, 동적할당은 수동이다. 그래서 동적할당은 요구와 반환을 따로 함수로 해주어야 된다. 그렇지 않으면 영원히 반환이 안돼서 메모리가 해제될 때까지 계속 남아있는 릭(leak)이 생기게 된다.
그런 일이 발생하지 않으려면 free(); 함수로 메모리를 해제해야 된다. 그 메모리는 malloc(); 으로 동적할당을 하는 경우에서이다. 그러면 왜 동적할당을 할까?
int nData[10]으로 변수를 선언했다고 하자. 이때 메모리는 4byte * 10으로 40바이트가 된다. 이 때 변수의 메모리 결정이 끝이 난다. 그래서 변수 선언은 메모리가 정확하게 알 수 없는 상황(런타임이 된 후에 메모리의 필요량이 결정되는 경우)일 경우에도 어쩔 수 없이 필요량과 어긋나는 메모리를 확보할 수밖에 없는 것이다.
이런 일을 막기 위해 동적할당을 쓴다. 수동으로 관리하기에 메모리확보에 있어서 자유로운 것이다.
알아둘 것
지난 시간 포인터와 배열은 거의 비슷하다고 했었다만, 여기서 이 둘의 차이는 관리와 사용의 차이라고 영상에 나온다. 그 이유는 위에 나온 메모리를 쓰는 과정과 관련 깊다. 메모리는 요구하고 사용하고 반환하는 3가지 과정을 거치는데, 여기서 배열은 직접 요구하는데 있어서 포인터와 차이가 난다. 포인터는 배열과 거의 동일하게 사용되지만, 배열처럼 직접 메모리를 확보하는 것이 아니기 때문이다.
추가로 코드에 나온 fflush()함수에 대해서도 추가설명이 있는데, 버퍼를 비운다고 지난시간 본 적 있는 이 함수는 윈도우에서만 쓰인다.(fflush(stdin)일 경우 입력버퍼의 데이터를 비우면서 삭제하고, fflush(stdout)일 경우 출력버퍼의 데이터를 비우면서 출력한다) 참고로 주의하자.
예시
char *pszBuffer = NULL; 로 포인터 변수를 만들고,(초깃값이 0이 아니고 존재하지 않는 메모리 주소다) int nInput = 0;으로 변수 선언을 해준다. 이 값이 scanf("%d", &nInput);에서 들어가는 수고, pszBuffer = (char *)malloc( nInput );으로 nInput으로 받은 scanf한 값만큼 메모리를 선언해주고, (자료형은 char *가 된다) 그 값을 pszBuffer로 넣어주는 것이다. fflush(stdin);으로 입력버퍼의 엔터를 없애주고, gets(pszBuffer); puts(pszBuffer);로 출력해준다. 마지막으로 free(pszBuffer);하면 끝! 그러면 스캔한 양만큼 메모리를 선언해주고 그 스캔 받은 내용을 출력할 수 있는 동적할당을 이용한 코드가 된다.