본문 바로가기

프로그래밍/C언어

[C언어 with Java] malloc, calloc & free, 힙 메모리 할당과 해제!

 

 

C Prog. with Java


C언어를 다루고 있지만, 다른 프로그래밍 언어인 자바와 비교하면서 내용을 구성하고 합니다. 본 글은, 자바를 먼저 어느정도 알고 계시고, 저와 같이 C언어를  공부하고자 하는 분들에게 도움이 되길 바랍니다.

 

 자바에서는 함수나 지역변수, 매개변수의 경우, 스택 메모리 영역에 할당이 되구요.  

객체는 생성과 동시에 힙 메모리 영역에 할당이 됩니다.

 

 스택의 경우, 메모리 구조를 보면 호출된 순서대로 쌓이고, 마지막에 쌓이것이 먼저 제거되는 특성을 가지고 있구요.

그래서, 이곳에 존재하는 지역변수나, 매개변수, 그리고 함수의 경우는 제거됨과 동시에 메모리 공간에서 없어집니다.

 

 하지만 힙 메모리의 경우는, 객체가 생성될 때 주로 이용이 되는데, 이곳에 위치하는 경우는 프로그램이 종료가 되거나, 이를 참조하는 값이 없어서 가비지 콜렉터에 의해서 사라지지 않는 이상, 계속해서 데이터가 유지됩니다.

 

 (자세한 내용은 다른글을 참고하시길 바랍니다.)

 

 자바에서는 자동으로 적절하게 메모리 공간을 할당하고, 활용할 수 있게 하지만,

C언어에서는 사용자가 직접 조작을 해야 합니다.

 

 특히, 힙 메모리를 사용하기 위해서 특정한 함수가 존재하는데요, 바로 "malloc" 입니다.

비슷하게 "calloc" 함수도 존재하나, 이글에선 다루지 않겠습니다.

 

  malloc 함수를 쓸려면 우선 다음과 같이 stdlib.h 헤더파일을 include 해야합니다.

#include <stdlib.h>

 

 그리고 정의되어 있는 malloc 함수와 설명은 다음과 같습니다. -msdn에서 참고

void *malloc(size_t size);

 

malloc returns a void pointer to the allocated space or NULL if there is insufficient memory available. To return a pointer to a type other than void, use a type cast on the return value. The storage space pointed to by the return value is guaranteed to be suitably aligned for storage of any type of object. If size is 0, malloc allocates a zero-length item in the heap and returns a valid pointer to that item. Always check the return from malloc, even if the amount of memory requested is small.

 

해석) malloc 은 할당된 공간에 대해 void 포인터를 반환하거나, 사용할 수 있는 충분한 공간이 없으면 NULL 값을 반환합니다. (..이하생략) 

 

 정의에서도 그렇고, 함수 부분을 보시면 void*, 즉, void 포인터를 반환하는 것을 확인 할 수 있는데요.

이 void 포인터의 경우, 간단히 "포인터형이 정해져 있지 않지만, 어떤 주소값을 담고 있다." 라고 생각하시면 될 것같아요.

자바로 비유를 들면, 물론 상황은 그렇지만, Object 클래스 타입이라고 생각하면 될까요? 사용할려면 형변환을 해서 사용하는 것처럼요. -지극히, 제 생각이며, 태클 가능하십니다 ^^-

 포인터 형이 정해져 있지 않기때문에,반환받은 void 포인터를 사용하기 위해서는 형변환을 해야 합니다.

사용법은 소스를 보시면 이해하시기 더 편할 거에요.

 

 그리고 소스를 보기 전에 매개변수를 보면, 매개변수 size 의 타입이 "size_t" 라는 것을 알 수 있는데요.

size_t 타입은 typedef 키워드에 의해 새로이 정의된 자료형입니다. 데이터의 크기를 담기 좋도록 unsigned int 로 선언되어 있다고 해요. 그래서 저기 매개변수에 100이라는 값을 넘겨주게 되면 힙 메모리에 사용자가 사용할 수 있는 100바이트의 공간이 할당됩니다.

 

 말이 길어졌는데, 소스를 보도록 할게요. - msdn 참고 및 변형

 

 우선, 여기서 "_MAX_PATH" 라는 값이 있는데, 소스 설명으로 보아 <stdlib.h>에 260이라는 길이로 정의되어 있는것 같습니다. 참고하세요.

 

 string이라는 char 형 포인터가 선언이 되었는데요, 여기에 malloc 함수를 써서 리턴 받은 주소값을 저장합니다.

그렇기 때문에 포인터를 정의해서 위와 같이 사용을 하구요. 그리고 malloc이 void 포인터기 때문에 형변환을 꼭 합니다.

어떤 타입의 데이터가 담겨있는지 모르기 때문에 알려줘야 합니다.

 

 실행을 시켜보면, 메모리 공간이 불충분할 경우에, 메모리 공간이 할당 되지 않아, 즉, malloc함수의 결과로 NULL이 반환되었 때에는

"Insufficient memory available"

이라는 메시지를 띄우고 프로그램이 종료됩니다.

 

 메모리 공간이 충분할 경우, 즉, malloc 함수의 결과가 NULL이 아닌 공간을 할당하고 주소를 반환하였을때,

"Memory space allocated for path name"

이라는 메시지를 띄웁니다. 그리고 할당받은 메모리 공간에 * 연산자를 통해 값을 넣습니다.

 

 이렇게 메모리 할당에 실패한 경우를 대비해서, 위와 같이 조거문을 통한 NULL 포인터의 반환여부를 확인하는 것이 좋습니다.

 

 여기서 보시면 free 라는 함수가 있는데요, 이는 malloc을 통해서 할당한 메모리 공간을 해제하는 역할을 합니다.

이 free 라는 함수를 통해서 할당받은 메모리 공간을 해제하지 않으면, 메모리 누수가 일어납니다. 자바의 경우, 가비지 콜렉터가 알아서 해주지만 C언어에서 프로그래머가 직접 해줘야 합니다.

 사용법은 malloc의 반환값을 저장하고 있는 변수를 넣어주면 됩니다.

 

 ** calloc은 malloc과 유사하지만, 사용법과 초기화 되는 방식이 다릅니다.

void *calloc(size_t num, size_t size);

 

 이렇게 매개변수가 두개로 정의 되는데요. malloc의 경우 매개변수가 하나라 100이라는 값을 넘겨주게 되면 바로 100 바이트라는 공간을 할당하지만, calloc은 두번째 매개변수 size에 명시된 크기만큼, 첫번째 매개변수 num 의 갯수를 생성하는 겁니다. 결국 이렇게 되겠네요

calloc(5, 20);

 

 20 * 5 =100. 이는 malloc(100) 과 동일한 결과를 보이겠습니다.

 

 그리고 다음의 설명을 유심히 보면, -msdn

The calloc function allocates storage space for an array of num elements, each of length size bytes. Each element is initialized to 0.

 

마지막에, "각 엘리먼트는 0으로 초기화 된다." 라는 것을 볼 수 있는데요. calloc 함수로 메모리 공간 할당시, 할당된 공간의 모든 비트를 0으로 초기화 한다는 말입니다. 그에 반해 malloc은 메모리 공간을 쓰레기 값으로 채워집니다.

 

 이정도의 차이만 있을 뿐 다른것은 없습니다. 메모리 공간을 해제할때도 역시 free 함수를 사용하구요.

 

 이상입니다~