- 소프트웨어 정글 5주차 두 번째 과제로 수행하였다.
- 묵시적 가용리스트를 수정하여 구현하였다.
수정된 부분
매크로
#define GET_ADD(p) (*(void **)(p))
#define PUT_ADD(p, val) (*(void **)(p) = (val))
- GET(p), PUT(p)의 경우, 주소에 저장된 값을 읽고 쓰는 매크로이다.
- 현재 필요한 매크로는 주소에 값으로 저장된 주소를 읽고 쓰는 것이므로 다른 타입으로 매크로를 사용하여야 한다.
- void ** 를 사용하여 주소의 주소를 저장하고, 역참조 연산자로 값을 꺼내는 방식을 썼다.
mm_init
int mm_init(void)
{
/* 초기 상태의 빈 heap을 만들어준다. */
if ((heap_listp = mem_sbrk(4*W_SIZE)) == (void *)-1)
return -1;
root = heap_listp;
PUT(heap_listp, 0); // Alignment padding
PUT(heap_listp + (1*W_SIZE), PACK(D_SIZE, 1)); // 프롤로그 헤더
PUT(heap_listp + (2*W_SIZE), PACK(D_SIZE, 1)); // 프롤로그 푸터
PUT(heap_listp + (3*W_SIZE), PACK(0, 1)); // 에필로그 헤더
heap_listp += (2*W_SIZE);
PUT_ADD(root, root+(4*W_SIZE)); // root에 초기 free 블록의 주솟값을 넣어준다.
/* 빈 힙을 CHUNKSIZE 바이트의 free된 블록으로 확장한다. */
if (extend_heap(CHUNKSIZE/W_SIZE) == NULL)
return -1;
/*explicit 추가로직*/
PUT_ADD(root+(4*W_SIZE), NULL); // 초기 free 블록 헤더 다음 위치에 NULL을 넣어준다().
PUT_ADD(root+(5*W_SIZE), NULL); // 초기 free 블록 헤더 다다음 위치에 NULL을 넣어준다.
return 0;
}
- Alignment padding을 root로 하여 구현하였다.
- root는 free 된 블록의 주소를 가리킨다.
- free 된 블록의 주소는 다음 블록의 주소를 가리킨다. 현재는 가장 뒤에 있는 블록이므로 NULL이 들어간다.
- free 된 블록의 주소의 워드 한 칸 뒤 주소는 이전 블록의 주소를 가리킨다. 현재는 가장 앞에 있는 블록이므로 NULL이 들어간다.
find_fit
// 수정 전
static void *find_fit(size_t asize) {
char *find_pos = GET_ADD(root);
while (GET_ADD(find_pos) != NULL ) { // 마지막 도달 전까지
if(GET_SIZE(HDR_P(find_pos)) < asize) { // 블록의 크기가 asize 보다 작으면 다음 탐색
find_pos = GET_ADD(find_pos);
} else {
return find_pos;
}
}
return NULL;
}

- first fit으로 구현 시, 위와 같은 메모리 초과 에러가 나왔다.
// 수정 후
void *find_fit(size_t size) {
void *best_fit = NULL;
size_t min_diff = (size_t) -1; // 가능한 가장 큰 차이 값으로 초기화
for (void *find_pos = GET_ADD(root); find_pos != NULL; find_pos = GET_ADD(find_pos)) {
size_t current_size = GET_SIZE(HDR_P(find_pos));
if (current_size >= size && (current_size - size) < min_diff) {
best_fit = find_pos;
min_diff = current_size - size;
}
}
return best_fit;
}