简单的实现 malloc free API (for studying)

    技术2025-10-11  12

    #include"xylib/xiuye" #include<sys/types.h> #include<unistd.h> #include<cstdio> using namespace xiuye; #define align4(x) (((((x)-1)>>2)<<2)+4) #define align8(x) (((((x)-1)>>3)<<3)+8) #define ptr_size sizeof(size_t) #define align(x) (((((x)-1)/ptr_size)*ptr_size)+ptr_size) typedef unsigned char byte; typedef struct s_block *t_block; struct s_block{ size_t size; t_block prev; t_block next; int free; void *ptr; // byte data[1]; }; #define BLOCK_SIZE sizeof(struct s_block) /* Of course , update the BLOCK_SIZE macro */ // # define BLOCK_SIZE 12 /* 3*4 ... */ void *base = NULL; t_block get_block(void*p){ // byte *tmp = (byte)p; // return (p = tmp -= BLOCK_SIZE); return (t_block)p - 1; } int valid_addr(void *p){ if(base){ if(p>base && p<sbrk(0)/*last break ptr*/){ return p == get_block(p)->ptr; } } return 0; } t_block find_block(t_block *last,size_t size){ t_block b = (t_block)base; while(b&&!(b->free&&b->size>=size)){ *last = b; b = b->next; } return b; } t_block extend_heap(t_block last,size_t s){ t_block b = (t_block)sbrk(0); if(sbrk(BLOCK_SIZE+s) == (void*)-1){ return NULL; } b->size = s; b->next = NULL; b->prev = last; b->ptr = b+1;//block + data,so +1 if(last){ last->next = b; } b->free = 0; return b; } void split_block(t_block b,size_t s){ // n = (t_block)(b->data+s); t_block new_block = (t_block)(b+1+s); new_block->size = b->size-s-BLOCK_SIZE; new_block->next = b->next; new_block->prev = b; new_block->free = 1; new_block->ptr = new_block+1; b->size = s; b->next = new_block; if(new_block->next){ new_block->next->prev = new_block; } } void *malloc(size_t size){ t_block b,last; size_t s; s = align(size); if(base){ last = (t_block)base; b = find_block(&last,s); if(b){ if((b->size-s) >= (BLOCK_SIZE+ptr_size)){ split_block(b,s); } b->free = 0; } else{ b = extend_heap(last,s); if(!b){ return NULL; } } }else{ b = extend_heap(NULL,s); if(!b){ return NULL; } base = b; } return b+1; // void *p; // p = sbrk(0); // if(sbrk(size) == (void*)-1){ // return NULL; // } // return p; } void *calloc(size_t number,size_t size){ size_t *new_ptr; size_t s,i; new_ptr = (size_t*)malloc(number*size); if(new_ptr){ s = align(number*size)/ptr_size; for(i=0;i<s;i++){ new_ptr[i] = 0; } } return new_ptr; } t_block fushion(t_block b){ if(b->next && b->next->free){ b->size += BLOCK_SIZE+b->next->size; b->next = b->next->next; if(b->next){ b->next->prev = b; } } return b; } void free(void *p){ t_block b; if(valid_addr(p)){ b = get_block(p); b->free = 1; if(b->prev && b->prev->free){ b = fushion(b->prev); } if(b->next){ fushion(b); } else{ if(b->prev){ b->prev->next = NULL; } else{ base = NULL; } brk(b); } } } void copy_block(t_block src,t_block dst){ size_t *sdata,*ddata; size_t i; sdata = (size_t*)src->ptr; ddata = (size_t*)dst->ptr; for(i=0;i*ptr_size<src->size && i*ptr_size<dst->size;i++){ ddata[i] = sdata[i]; } } void out_ptr_block(void *p){ t_block q = get_block(p); println("block:",q,"size:",q->size,"prev:",q->prev,"next:",q->next,"free",q->free,"ptr:",q->ptr); } int main(){ //估计和 标准库 malloc filename 冲突了等原因! //不能用 // line(111111); printf("%d\n",BLOCK_SIZE); printf("int:%d\n",sizeof(int)); printf("t_block:%d\n",sizeof(t_block)); printf("s_block:%d\n",sizeof(struct s_block)); char s[1]; printf("char s[1] s:%d\n",sizeof(s)); printf("long:%d\n",sizeof(long)); println(align4(1),align4(2),align4(3),align4(4),align4(5)); println(sizeof(size_t)); s_block b; println(sizeof(b.size),sizeof(b.next),sizeof(b.free)); println(align(1),align(2),align(3),align(4),align(5)/8); int *p1; println(p1,p1+1,p1+2); char s1[1]; char s2[10]; println(sizeof(s1),sizeof(s2)); int *p = (int*)malloc(sizeof(int)); out_ptr_block(p); println(p,*p); *p = 100; println(p,*p); free(p); out_ptr_block(p); int *pa = (int*)calloc(10,sizeof(int)); out_ptr_block(pa); // for(int i=0;i<10;i++){ // println(i,pa[i],sizeof(pa[i]),sizeof(pa)); // } println(pa); free(pa); out_ptr_block(pa); return 0; } 40 int:4 t_block:8 s_block:40 char s[1] s:1 long:8 4 4 4 4 8 8 8 8 4 8 8 8 8 1 0 0x4 0x8 1 10 block: 0x21cec28 size: 8 prev: 0x21bd000 next: 0 free 0 ptr: 0x21cec50 0x21cec50 0 0x21cec50 100 block: 0x21cec28 size: 8 prev: 0x21bd000 next: 0 free 1 ptr: 0x21cec50 block: 0x21cec28 size: 40 prev: 0x21bd000 next: 0 free 0 ptr: 0x21cec50 0x21cec50 block: 0x21cec28 size: 40 prev: 0x21bd000 next: 0 free 1 ptr: 0x21cec50

     

    Processed: 0.009, SQL: 9