이번 장에서는 UNIX/C의 메모리 관리 인터페이스에 대해 논의한다.
(여기서의 메모리는 "사용자 주소 공간"을 의미함)
핵심 질문: 어떻게 메모리를 할당하고 관리해야 하는가
일반적으로 어떤 인터페이스가 사용되는가?
어떤 실수를 해서는 안 되는가?
C 프로그램이 실행되면 스택 메모리와 힙 메모리에 공간이 할당된다.
스택 메모리
x
선언하면 스택 메모리에 공간 할당void func(){
int x; // 스택에 int 형을 선언
}
힙 메모리
void func(){
int* x = (int*) malloc(sizeof(int));
}
malloc()
을 오출하여 x
를 위한 공간을 할당하는 것은 힙으로부터 요구x
에 할당된 메모리 공간이 해제되지 않고 계속 남아있음malloc()
함수
#include<stdlib.h>
...
void* malloc(size_t size);
size
)를 넘겨주면, 할당된 공간에 대한 포인터를 사용자에게 반환NULL
반환 size
자리에 sizeof(자료형)
가 들어감malloc(strlen(s) +1)
을 해줘서 맨 뒤에 \0
을 위한 공간까지 할당함void*
형이라 저절로 타입이 변환됨 (type casting)sizeof()
연산자
sizeof
는 함수가 아니고, 컴파일 시간에 값이 결정됨 (함수는 런타임에 값 결정)int* ptr = (int*)malloc(10*sizeof(int));
printf(“%d\n”,sizeof(ptr)); // -> 4 or 8
sizeof(ptr)
이런식으로 포인터를 넣으면, 포인터가 가리키는 놈의 주소가 아닌 포인터 자체의 크기 반환int arr[10];
printf(“%d\n”,sizeof(arr)); // -> 40
sizeof(arr)
이런식으로 배열을 넣으면, 배열의 크기가 잘 나옴free()
: 할당된 힙 메모리를 해제하는 함수
malloc()
과 free()
사용할 때 발생하는 오류들이 많다. C언어는 자동 메모리 관리를 지원하지 않기 때문이다.
자동 메모리 관리(automatic memery management)
new
키워드로 새 객체 할당char *dst;
이런식으로 선언만 하고 메모리 할당을 안 하는 경우char* src="hello";
char*dst = (char*)malloc(strlen(src)); // srtlen(src) +1 해줘야함
strcpy(dst,src); // 동작하기는 하나, 위험```
malloc()
을 제대로 호출했지만 값 안 넣는것free()
호출한 후에 해당 포인터 사용하려고 할 때 발생free()
는 malloc()
이 받은 포인터만 전달될 것으로 예상malloc()
과 free()
는 시스템 콜이 아니라 라이브러리 함수다.
메모리 관련 시스템 콜
calloc()
: 메모리 할당 영역을 0으로 채워서 반환realloc()
: 이미 할당된 공간에 대해 추가 공간이 필요할 때 사용