malloc은 블록 내에 포함될 수 있는 데이터 객체에 대해서 적절히 정렬된 최소 size 바이트를 가지는 메모리 블록의 포인터를 리턴한다.
프로그램이 malloc이 할당한 메모리보다 더 큰 메모리를 요구하는 경우 NULL을 리턴 -> errno를 설정
malloc은 mmap과 munmap 함수를 사용해서 명시적으로 힙메모리를 할당하거나 반환 / sbrk 함수를 사용
sbrk 함수는 커널의 brk포인터에 incr을 더해서 힙을 늘리거나 줄인다.
free 함수를 사용해 할당된 힙 블록을 반환
종종 프로그램들이 실제 실행시키기 전에 자료구조의 크기를 알 수 없는 경우가 많음
가장 간단한 방법은 배열을 정해진 최대 크기를 가진 정적 배열을 생성하는 것
문제점: 사용자가 임의로 정한 최대크기보다 더 큰 메모리를 사용할려고 하면 error
따라서 자료구조의 크기를 알 수 있을 때 배열을 런타임에 할당하는 것
단편화는 가용메모리가 할당 요청을 만족시키기에 부족할 때 일어난다. 단편화에는 2종류의 단편화가 있다.
1. 내부단편화: 할당된 블록이 데이터 자체보다 클 때 일어난다.
- 내부단편화는 정령화하기가 간단하다. 이것은 단순히 할당된 블록의 크기와 이들의 데이터 사이의 차이의 합이다.
2. 외부단편화: 할당 요청을 만족시킬 수 있는 메모리 공간이 전체적으로 봤을 때는 크키가 충분하지만 이 요청을 처리하기에 블록들이 떨어져있을 때 발생한다.
- 외부단편화는 내부단편화보다 측정하기가 힘들다. 이전 요청의 패턴과 할당기 구현에만 의존하는 게 아니라 미래의 요청이 어떻게 될 지 모르기 때문이다.
- 외부단편화는 측정하기 어렵고 예측하기 어렵기때문에 할당기들은 대게 많은 수의 작은 가용 블록들보다는 더 적은 수의 큰 가용블록들을 유지하는 방법들을 사용한다.
모든 실용적인 할당기들은 블록 경계를 구분하고 할당된 블록과 가용블록을 구분하는 데이터 구조가 필요하다.
대부분의 할당기들은 이 정보를 블록 내에 저장한다.
단순한 접근법에서 한 블록은 1워드 헤더, 데이터, 패딩(optional)로 구성된다.
헤더는 블록의 크기와 블록이 할당된 상태인지를 인코딩해서 나타낸다.
1. 000은 free
2. 001은 Allocated
> 17바이트를 할당해야하면 8의 배수로 맞추는게 할당기가 검색할 때 더 빨라지므로 추가적인 워드를 주더라도 이를 24바이트에 맞춤
묵시적 가용리스트의 장점은 단순성이다.
중요한 단점은 연산들의 비용이 힙에 있는 전체 할당된 블록과 가용 블록의 수에 비례한다는 것이다.
프로그램이 K바이트의 블록을 요청하면 할당기는 요청한 블록을 저장할 수 있는 큰 가용 블록을 리스트에서 검색한다. 할당기가 이 검색을 수행하는 방법은 배치 정책에 의해서 결정된다.
주로 first fit, next fit, best fit이 사용된다.
할당기가 크기가 맞는 가용 블록을 찾으면 가용블록의 어느 정도를 할당할 지 결정해야한다.
제일 단순한 옵션은 가용 블록의 전체를 사용하는 것이다. 간단하고 빠르긴 하지만 큰 단점은 내부 단편화가 생긴다는 것이다.
가용 블록이 할당할려는 블록보다 큰 경우 필요한 만큼만 분할해서 할당하고 나머지 부분을 free 상태로 둔다.
prologue header/footer: 힙의 시작을 알리는 블록
- prologue header: 메모리 할당구조를 구성하는 블록으로써, 가장 처음 생성되는 블록, 다음과 같은 정보를 담고 있음
- 블록의 크기
- 블록의 사용 여부 (0 or 1)
epilogue block header: 힙의 끝을 알리는 블록
epilogue block header: heap의 끝을 나타내는 특별한 block header. -> 마지막 block의 header와 footer의 역할을 수행
epilogue block header의 크기는 0이며 이를 통해 heap의 끝을 나타냄.
footer가 필요한 이유는 block header와 연결된 block의 크기 정보를 포함하기 때문
오류 단편화: 할당된 블록이 반환됐을 때 인접한 곳에 가용블록이 있지만 작은 블록인 상태로 존재하는 것을 말한다. 이를 해결하기 위해 연결하는 과정이 필요하다.