2 minute read

Memory API

Memory Virtualization을 공부하기 전에 memory가 어떻게 할당되고 관리되는 지를 memory API를 통해 이해할 수 있다.

C 언어가 사용하는 memory에는 크게 두 가지가 존재한다. 첫 번째는 stack으로 compiler가 자동으로 채우고 지워주는 memory이다. 만약 실행한 함수 안에 호출된 다른 함수나 local variable이 존재하면 stack에 자동으로 추가되고 이 실행한 함수가 return 되면 자동으로 이 data가 없어진다.

하지만 Heap은 stack과 다르게 programmer가 직접 관리해야 하는 memory이다.


void func(){
    int x;
}

이 코드가 실행되었다고 해보자. 그러면 x는 local variable이기에 stack에 저장된다. 이와 동시에 heap에도 저장된다. malloc()는 heap에 메모리를 할당해주는 memory API이기 때문이다. 이처럼 memory API는 모두 heap과 밀접하게 연관되어있다.

malloc()

void* malloc(size_t size)는 지정한 크기 size만큼 heap에 공간을 생성해주고 그 공간을 지칭하는 pointer을 반환해준다.

따라서 다음 코드를 실행했다고 해보자


int *x = malloc(10*sizeof(int));

printf("%d\n", sizeof(x));

malloc()는 pointer을 반환하기에 print되는 크기는 10*4 byte가 아니라 pointer의 크기 (4/8)일 것이다.

하지만 이 코드는 다르다


int x[10];
printf("%d\n", sizeof(x));

이 코드에서는 x가 10*4 byte의 크기로 나온다. 즉, malloc()은 pointer을 반환해준다는 것을 기억해야 한다.

또, string을 malloc에 저장하고 싶을 때 sizeof(string)을 사용하면 오류가 난다. C에서 모든 string은 ‘\n’이 끝에 붙어있기 때문이다. 따라서 strlen(s)+1로 malloc을 하는 것이 안전하다.

free()

free()는 단순히 malloc으로 할당된 공간을 비우는 API이다.


int *x = malloc(10 * sizeof(int));
free(x);

Common Errors

malloc와 free을 사용하면서 자주 생기는 오류들이 있다.

Forgetting to Allocate Memory

char *src = "hello";
char *dst; // oops! unallocated
strcpy(dst, src); // segfault and die

이 코드처럼 dst에는 memory을 할당하지 않고 사용하게 되면 segmentation fault 오류가 발생한다. Segmentation fault는 할당되지 않은 공간에 접근할 때 생기는 오류이다.

이 오류를 고치기 위해서는 그냥 dst에 memory을 할당해주면 되는 것이다.

char *src = "hello";
char *dst = (char *) malloc(strlen(src) + 1);
strcpy(dst, src); // work properly

Not Allocating Enough Memory

joowan1108

충분하지 않은 memory을 할당하면 buffer overflow라는 오류가 생긴다.

char *src = "hello";
char *dst = (char *) malloc(strlen(src)); // too small!
strcpy(dst, src); // work properly

이 코드는 실행은 잘 되지만 string을 heap에 저장하기 위해서는 strlen(src) + 1만큼 메모리를 할당해야 한다. 실행은 되더라도 나중에 오류가 생길 가능성이 매우 높다.

Forgetting to Initialize Allocated Memory

joowan1108

malloc()을 통해 pointer와 memory을 할당받더라도 그 memory 안에 data을 채워넣어야 한다. 그렇지 않으면 garbage data가 읽힐 수 있다.

Forgetting to Free Memory

할당된 memory는 다 쓰고 나서 free을 해야 한다. 그렇지 않으면 나중에 사용 가능한 memory가 점점 줄어들어 결국 memory 부족으로 프로그램이 제대로 실행되지 못할 수 있기 때문이다.

Freeing Memory Before You are Done with it

joowan1108

Memory 사용이 끝나기 전에 free을 하면 dangling pointer라는 문제가 생긴다.

Freeing Memory Repeatedly

동일한 memory 공간에 대해 free을 여러번 하면 예상하지 못한 결과가 나올 수 있다.

Calling free() incorrectly

Free() 안에는 malloc을 통해 할당받은 메모리를 가르키는 pointer가 들어가야 하는데 이 값이 들어가지 않는다면 오류가 생긴다.