diff --git a/alloc.c b/alloc.c index 931b9fd59da6368f6a48cfa9f681133f918b162b..f3ade4777f0c93db663a7cf82aad33e5affdbb06 100644 --- a/alloc.c +++ b/alloc.c @@ -1 +1,198 @@ #include "alloc.h" + +static meta p_meta = NULL; + +void *origin=NULL; + +void *m_malloc(size_t size){ + + if(p_meta == NULL || sbrk(0) == origin){ + origin = sbrk(0); + p_meta = sbrk(size + sizeof(struct meta_struct)); + p_meta->prev = NULL; + p_meta->next = NULL; + p_meta->size = size; + p_meta->free = 0; + + return (void *)(p_meta+sizeof(struct meta_struct)); + } + + meta new = p_meta; + meta pre = p_meta; + + if(fit == 'F'){ + while(new){ + if( (new->free == 1) && (size <= new->size) ){ + break; + } + pre = new; + new = new->next; + } + } + if(fit == 'B'){ + meta tmp = NULL; + int chk=0; + while(new){ + if( (new->free == 1) && (size <= new->size) ){ + if(tmp == NULL) + tmp = new; + if(new->size <= tmp->size){ + tmp = new; + chk = 1; + } + } + pre = new; + new = new->next; + } + if(chk == 1) + new = tmp; + } + if(fit == 'W'){ + meta tmp = NULL; + int chk=0; + while(new){ + if( (new->free == 1) && (size <= new->size) ){ + if(tmp == NULL) + tmp = new; + if(new->size >= tmp->size){ + tmp = new; + chk = 1; + } + } + pre = new; + new = new->next; + } + if(chk == 1) + new = tmp; + } + + if(new == NULL){ + new = sbrk(0); + sbrk(size + sizeof(struct meta_struct)); + new->prev = pre; + new->next = NULL; + new->size = size; + new->free = 0; + + pre->next = new; + + return (void *)(new+sizeof(struct meta_struct)); + } + else{ + pre = new; + new = (void *)(pre + size + sizeof(struct meta_struct)); + new->prev = pre; + new->next = pre->next; + new->size = pre->size - size; + new->free = 1; + if(new->next != NULL) + new->next->prev = new; + + if(new->size == 0){ + if(new->next != NULL) + new->next->prev = new->prev; + new = new->next; + } + pre->next = new; + pre->size = size; + pre->free = 0; + return (void *)(pre + sizeof(struct meta_struct)); + } +} + +void *m_free(void *ptr){ + + meta cur = ptr; + cur = (void *)(cur-sizeof(struct meta_struct)); + cur->free = 1; + + if(cur->prev == NULL && cur->next == NULL){ + brk(origin); + } + else if(cur->next == NULL){ + cur->prev->next = NULL; + brk(cur); + } + + if(cur->next != NULL && cur->next->free == 1){ + cur->size = cur->size + cur->next->size; + if(cur->next->next != NULL) + cur->next->next->prev = cur; + cur->next = cur->next->next; + } + if(cur->prev != NULL && cur->prev->free == 1){ + cur->prev->size = cur->size + cur->prev->size; + if(cur->prev->prev != NULL) + cur->prev->prev->next = cur->prev; + cur->next->prev = cur->prev; + cur->prev->next = cur->next; + } + + +} + +void *m_realloc(void *ptr,size_t size){ + meta new = ptr; + new = (void *)(new-sizeof(struct meta_struct)); + + if(size > new->size){ + if(new->next == NULL){ + sbrk(size - new->size); + new->size = size; + + return (void *)(new+sizeof(struct meta_struct)); + } + else if(new->next != NULL && new->next->free == 1){ + if( (new->size + new->next->size) > size){ + new->next = (void *)new + sizeof(struct meta_struct) + size; + new->next->size = (new->size + new->next->size) - size; + new->next->prev = new; + new->next->free = 1; + + return (void *)(new+sizeof(struct meta_struct)); + } + else if((new->size + new->next->size) == size){ + new->next = new->next->next; + new->next->next->prev = new; + new->size = size; + + return (void *)(new+sizeof(struct meta_struct)); + } + else{ + meta tmp = m_malloc(size); + memcpy(tmp,new,size); + m_free(ptr); + + return (void *)(tmp+sizeof(struct meta_struct)); + } + } + else{ + meta tmp = m_malloc(size); + tmp = (void *)(tmp-sizeof(struct meta_struct)); + + memcpy((void *)(tmp+sizeof(struct meta_struct)), + (void *)(new+sizeof(struct meta_struct)), + (size+sizeof(struct meta_struct))); + m_free(ptr); + + return (void *)(tmp+sizeof(struct meta_struct)); + } + } + else{ // size < ptr->size + meta tmp = (void *)new + sizeof(struct meta_struct) + size; + tmp->prev = new; + tmp->next = new->next; + tmp->next->prev = tmp; + tmp->size = new->size - size; + tmp->free = 1; + + new->next = tmp; + new->size = size; + memcpy(new,ptr,(size+sizeof(struct meta_struct))); + + return (void *)(new+sizeof(struct meta_struct)); + } +} + + + diff --git a/alloc.h b/alloc.h index 3245f55c3496bc75c70c04625ca3dcb7dd5d0afd..021daa477b5586275afc76aa6e35a277868f616b 100644 --- a/alloc.h +++ b/alloc.h @@ -1,8 +1,24 @@ +#include<stdio.h> + #ifndef _ALLOC_H_ #define _ALLOC_H_ -typedef struct meta_struct { +typedef struct meta_struct *meta; + +struct meta_struct { + meta prev; + meta next; + + unsigned int free; + + unsigned int size; +}; -} meta; +extern char fit; +extern void *origin; #endif + +void *m_malloc(size_t size); +void *m_free(void *ptr); +void *m_realloc(void *ptr,size_t size); diff --git a/main.c b/main.c index b5fba0682b01a1005462aa24bf4ac2f21227e156..61c57d6b72bd4b27bc1b04e24baf58c1e0b8e679 100644 --- a/main.c +++ b/main.c @@ -1,6 +1,70 @@ #include "alloc.h" +#include<unistd.h> -int main() -{ +char fit = 0; + +int main(){ + int cnt; + scanf("%d %c",&cnt,&fit); + + char **content; + content = (char **)malloc(sizeof(char *) * cnt); + + int i,n,m; + char cmdtype; + char buf[1024]={0}; + int strcount=0; + for(i=0;i<cnt;i++){ + scanf("\n%c ",&cmdtype); + if(cmdtype == 's'){ + strcount++; + fgets(buf,1024,stdin); + int len = strlen(buf)-1; + buf[len]='\0'; + + size_t sz = len/4; + if(len%4 != 0) + sz += 1; + content[i] = m_malloc(sz*4); + + strcpy(content[i],buf); + } + else if(cmdtype == 'f'){ + scanf("%d",&n); + + int j=0; + meta tmp = origin; + while(tmp && j != n){ + tmp = tmp->next; + j++; + if(j == n) + break; + } + m_free((void *)(tmp+sizeof(struct meta_struct))); + } + else if(cmdtype == 'r'){ + scanf("%d %d",&n,&m); + content[n] = m_realloc(content[n],m); + } + else if(cmdtype == 'e'){ + scanf("%d",&n); + content[i] = m_malloc(n); + + meta tmp = content[i]; + tmp = (void *)(tmp-sizeof(struct meta_struct)); + tmp->free = 1; + } + } + + meta tmp = origin; + while(tmp){ + + printf("%d %d ",tmp->free,tmp->size); + if(tmp->free == 0) + printf("%s",tmp+sizeof(struct meta_struct)); + printf("\n"); + tmp = tmp->next; + } + return 0; }