diff --git a/alloc.c b/alloc.c index 931b9fd59da6368f6a48cfa9f681133f918b162b..b0f351da1126e0bfdd076d9e4b368f6e5ff2b4fb 100644 --- a/alloc.c +++ b/alloc.c @@ -1 +1,143 @@ -#include "alloc.h" +#include "alloc.h"즈 +#define MSIZE sizeof(meta_struct)-4 + +void* total = 0; +void* base = 0; +void* end = 0; +void* cur = 0; +int fit;//0 1 2 + +meta* search(void* ptr, size_t size){//current pointer + mata* index = base; + meta* result = 0; + + if(base == ptr) + return 0; + + switch(fit){ + case 0://first fit + while(index){ //처음만나는 free가 0이 아닌것에 넣고 탈출 + if(index->free == 1 && index->size >= size){ + result = index; + break; + } + index = index->next; + } + break; + case 1://best fit + while(index){ + if(index->free == 1 && index->size >= size){ + if(result->size > index->size) + result = index; //조건을 충족 시킬때, result보다 작으면update + } + index = index->next; + } + break; + case 2://worst fit + while(index){ + if(index->free == 1 && index->size >= size){ + if(result->size < index->size) + result = index; //조건을 충족 시킬때, result보다 크면update + } + index = index->next; + } + break; + }return result; +} + +void *m_malloc(size_t size){ + if(base == 0){ + end = cur = total = base = sbrk(0); //sbrk 주소반환 + } + + if((size%4) != 0) + size = (size/4+1)*4; + + meta* target = search(total, size); //find chunk + + if(target == 0){ + meta* new = total; + meta* now = cur; + + sbrk(total + size + MSIZE); + now->next = new; + new->prev = now; + if(total = cur) + new->prev = 0; + + new->next = 0; + new->free = 0; + new->size = size; + cur = new; + + total = total + size + MSIZE; + return new->data; + }else{ + m_realloc(target->data, size); + } + return target->data; +} + +void m_free(void *ptr){ + meta* target; + target = ptr - MSIZE; + target->free = 1; + + if(target->prev != NULL){ + if(target->prev->free == 1){ //이전이 비어있으면 합침 + target->prev->size = target->prev->size + target->size + MSIZE; + target->prev->next = target->next; + target->next->prev = target->prev; + } + if(target->next == NULL) //prev는 있지만 next가 없을때 + target->prev->next = NULL; + } + if(target->next != NULL){ //next가 있을때 + if(target->next->free == 1){ //다음이 비어있으면 합침 + target->next->size = target->next->size + target->size + MSIZE; + target->next->prev = target->prev; + target->prev->next = target->next; + } + } +} + +void* m_realloc(void* ptr, size_t size){ + meta* old = ptr - MSIZE; //meta 제외 사이 + + if(size%4 != 0){ + size = (size/4 + 1)*4; //4배수 맞추기 + } + + if(old->size == size) return ptr; + if(old->next != NULL){ + if(old->next->free == 1){ + old->size = old->size + old->next->size + MSIZE; + old->next = old->next->next; + old->next->prev = old; + } + } + else if(old->size < size){ + old->free = 1; + meta* new = m_malloc(size); + memcpy(new, ptr, size); + return new; + } + else if(old->size < size + MSIZE){ + return ptr; + } + else{ + meta* new = old + size + MSIZE; + + new->free = 1; + new->next = old->next; + new->prev = old; + new->size = old->size - size - MSIZE; + + old->next = new; + old->size = size; + old->free = 0; + + m_free(new->data); + return old->data; + } +} diff --git a/alloc.h b/alloc.h index 3245f55c3496bc75c70c04625ca3dcb7dd5d0afd..82597d40df64f7adb7093b9197793473666a60d2 100644 --- a/alloc.h +++ b/alloc.h @@ -2,7 +2,14 @@ #define _ALLOC_H_ typedef struct meta_struct { + //double linked list + struct meta* prev; + struct meta* next; + size_t size; + bool free; + //char* data; //for string pointer + char data[1]; } meta; #endif diff --git a/main.c b/main.c index b5fba0682b01a1005462aa24bf4ac2f21227e156..51b40c8b339b31bf41f3c136846c45b78646bc16 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,7 @@ #include "alloc.h" +extern int fit; + int main() { return 0;