diff --git a/alloc.c b/alloc.c index 931b9fd59da6368f6a48cfa9f681133f918b162b..883234f02ea5bce2f8e61c3753d2de5a1f3d7f92 100644 --- a/alloc.c +++ b/alloc.c @@ -1 +1,195 @@ #include "alloc.h" + +#ifndef _SYS/TYPES_H_ +#define _SYS/TYPES_H_ +#include <sys/types.h> +#endif + +#ifndef _STDIO_H_ +#define _STDIO_H_ +#include <stdio.h> +#endif + +void *base=0; +void *end=0; +meta *find_location(size_t size); +extern int type=FIRST; + +void *m_malloc(size_t size) +{ + meta *target; + + if(base==0){ + base=sbrk(0); + end=base; + } + if(size%4!=0){ + size=(size/4+1)*4; + } + size_t len=size+METASIZE; + if(end==base) + target=-1; + else{ + target=find_location(size); + } + if(target==-1 || (!target->next && (!target->free || target->free && target->size<size))){ + meta *new=end; + end+=len; + if(sbrk(len)==-1){ + return 0; + } + new->free=0; + new->next=0; + new->prev=target; + new->size=size; + if(target!=-1){ + target->next=new; + } + target=new; + }else{ + m_realloc(target->data,size); + } + return target->data; +} + +void m_free(void *point) +{ + meta *current=point-METASIZE; + current->free=1; + if(current->next && current->next->free==1){ + current->size+=current->next->size + METASIZE; + current->next=current->next->next; + } + if(current->prev!=-1){ + if(current->prev->free){ + current=current->prev; + current->size+=current->next->size+METASIZE; + current->next=current->next->next; + } + if(!current->next){ + end-=current->size+METASIZE; + current->prev->next=0; + } + }else if(!current->next && !current->prev) + end=brk(base); + point=0; +} + +meta *find_location(size_t size) +{ + meta *index=base,*location=-1; + int max=0; + int min=2e9; + switch(type){ + case FIRST: + for(;;){ + if(index->free && index->size>=size){ + location=index; + break; + } + if(index->next==NULL){ + location=index; + break; + } + index=index->next; + if(index==NULL) + break; + } + break; + case BEST: + for(;;){ + if(index->free == 1 && index->size >= size && index->size<min){ + location=index; + min=index->size; + } + if(location==-1 && !index->next) + location=index; + index = index->next; + if(index) + break; + } + break; + case WORST: + for(;;){ + if((index->size)>=size && index->free){ + if(index->size>max) + location=index; + } + if(location==-1 && !index->next) + location=index; + index=index->next; + if(index) + break; + } + break; + } + return location; +} + + +void *m_realloc(void* pointer, size_t size){ + meta *current = pointer-METASIZE; + + if(size%4!=0){ + size=(size/4+1)*4; + } + + if(current->size == size) + return pointer; + + else if(current->size < size){ + if(current->next && current->next->free && current->size + current->next->size + METASIZE>=size){ + current->size += current->next->size + METASIZE; + current->next = current->next->next; + current->next->prev = current; + if(((current->size)-size) < METASIZE){ + return pointer; + }else{ + meta *new = (int)current + size + METASIZE; + new->prev = current; + new->next = current->next; + new->size = current->size - size - METASIZE; + current->next = new; + current->size = size; + current->free = 0; + m_free(new->data); + return current->data; + } + }else { + m_free(current->data); + void * new = m_malloc(size); + strcpy(new, pointer); + return new; + } + } + else if(((current->size)-size) < METASIZE){ + return pointer; + } + else{ + meta *new = (int)current + size + METASIZE; + new->prev = current; + new->next = current->next; + new->size = current->size - size - METASIZE; + current->next = new; + current->size = size; + current->free = 0; + m_free(new->data); + return current->data; + } +} + +void print_list() +{ + meta *current=base; + + while(current) + { + printf("%d %d ",current->free,current->size); + if(!current->free) + printf("%s\n",current->data); + else + printf("\n"); + current=current->next; + } + +} diff --git a/alloc.h b/alloc.h index 3245f55c3496bc75c70c04625ca3dcb7dd5d0afd..f6af3e99735af921ccb45c37f02df9e4d1375759 100644 --- a/alloc.h +++ b/alloc.h @@ -1,8 +1,35 @@ +#ifndef _STDINT_H_ +#define _STDINT_H_ +#include <stdint.h> +#endif + +#ifndef _SYS/TYPES_H_ +#define _SYS/TYPES_H_ +#include <sys/types.h> +#endif + #ifndef _ALLOC_H_ #define _ALLOC_H_ +#define FIRST 1 +#define BEST 2 +#define WORST 4 +#define METASIZE 16 + +extern int type; + typedef struct meta_struct { +uint32_t size; +uint32_t free; +struct meta_struct *next; +struct meta_struct *prev; +char data[1]; } meta; +void *m_malloc(size_t size); +void m_free(void *point); +void *m_realloc(void* point,size_t size); + #endif + diff --git a/input.txt b/input.txt new file mode 100644 index 0000000000000000000000000000000000000000..ec819f39fd0e673a9e83429ba096192ee2e9f415 --- /dev/null +++ b/input.txt @@ -0,0 +1,4 @@ +3 F +s Think like a man of action and act like man of thought. +s Courage is very important. Like a muscle, it is strengthened by use. +s Life is the art of drawing sufficient conclusions from insufficient premises. diff --git a/input2.txt b/input2.txt new file mode 100644 index 0000000000000000000000000000000000000000..ade2e2275d7716b5a98e75f5b03e3ab90e2e23f8 --- /dev/null +++ b/input2.txt @@ -0,0 +1,3 @@ +2 F +m Think like a man of action and act like man of thought +f 0 diff --git a/main b/main new file mode 100755 index 0000000000000000000000000000000000000000..a8a6e8028784e210abe492a407bd71959de8368e Binary files /dev/null and b/main differ diff --git a/main.c b/main.c index b5fba0682b01a1005462aa24bf4ac2f21227e156..0fc6174f151f8103ed9312f118da4606e45547a0 100644 --- a/main.c +++ b/main.c @@ -1,6 +1,79 @@ +#include <stdio.h> +#include <string.h> #include "alloc.h" -int main() +extern int type; + +int main(int argc,char *argv[]) { + + if(argc!=2){ + printf("err\n"); + printf("run with input.txt\n"); + return 1; + } + + FILE *input; + if((input=fopen(argv[1],"r"))==NULL){ + printf("err open input file\n"); + return 1; + } + char buf[4096]; + char *tok; + int i=0; + + fgets(buf,sizeof(buf),input); + tok=strtok(buf," "); + int line; + if((line=atoi(tok))==0){ + printf("Format Err\n"); + return 1; + } + tok=strtok(NULL," "); + switch(tok[0]){ + case 'F'://first fit + type=FIRST; + break; + case 'B'://best fit + type=BEST; + break; + case 'W'://worst fit + type=WORST; + break; + default://err + printf("wrong format\n"); + exit(1); + } + + char **list=(char**)malloc(sizeof(char*)*line); + int j=0,after_size,tmp; + for(i=0;i<line;i++){ + memset(buf,'\0',sizeof(buf)); + fgets(buf,sizeof(buf),input); + buf[strlen(buf)-1]='\0'; + switch(buf[0]){ + case 'm': + case 's': + list[j]=m_malloc(strlen(buf+2)+1); + strcpy(list[j++],buf+2); + break; + case 'f': + tmp=atoi(buf+2); + m_free(list[tmp]); + break; + case 'r': + tok=strtok(buf+2," "); + tmp=atoi(tok); + tok=strtok(NULL," "); + after_size=atoi(tok); + m_realloc(list[tmp],after_size); + break; + case 'e': + tmp=atoi(buf+2); + list[j++]=m_malloc(tmp); + break; + } + } + print_list(); return 0; }