zoukankan      html  css  js  c++  java
  • 简单显示分配器的实现

    没有什么难以理解的地方

    static void *heap_listp;
    
    extern int mm_init(void);
    extern void *mm_malloc(size_t size);
    extern void mm_free(void *ptr);
    
    static void *extend_heap(size_t words);
    static void *coalesce(void *bp);
    static void *find_fit(size_t asize);
    static void *place(void *bp,size_t asize);
    /*Basic constants and macros*/
    #define WSIZE 4              /*Word and header/footer size(bytes)*/
    #define DSIZE 8              /*Double word size (bytes)*/
    #define CHUNKSIZE (1<<12)    /*Extend heap by this amout (bytes)*/
    
    #define MAX(x,y) ((x) > (y)? (x):(y))
    
    /*Pack a size and allocated bit into a word*/
    #define PACK(size,alloc) ((size) | (alloc))
    
    /*Read and write a workd at address p*/
    #define GET(p) (*(unsigned int*)(p))
    #define PUT(p,val) (*(unsigned int*)(p) = (val))
    
    /*Read the size and allocated fields from address p*/
    #define GET_SIZE(p) (GET(p) & ~0x7)
    #define GET_ALLOC(p) (GET(p) & 0x1)
    
    /*Given block ptr bp,comute address of its header and footer*/
    #define HDRP(bp) ((char*)(bp)-WSIZE)
    #define FTRP(bp) ((char*)(bp)+GET_SIZE(HDRP(bp))-DSIZE)
    
    /*Given block ptr bp,compute address of next and previous blocks*/
    #define NEXT_BLKP(bp) ((char*)(bp)+GET_SIZE(((char*)(bp)-WSIZE)))
    #define PREV_BLKP(bp) ((char*)(bp)-GET_SIZE(((char*)(bp)-DSIZE)))
    
    int mm_init(void) {
      /*Create the initial empty heap*/
      if((heap_listp = mem_sbrk(4*WSIZE)) == (void*)-1) return -1;
      PUT(heap_listp,0);                          /*Alignment padding*/
      PUT(heap_listp+(1*WSIZE),PACK(DSIZE,1));    /*Prologue header*/
      PUT(heap_listp+(2*WSIZE),PACK(DSIZE,1));    /*Prologue footer*/
      PUT(heap_listp+(3*WSIZE),PACK(0,1));        /*Epilogue header*/
      heap_listp+=(2*WSIZE);
    
      /*Extend the empty heap with a free block of CHUNKSIZE bytes*/
      if(extend_heap(CHUNKSIZE/WSIZE) == NULL) return -1;
      return 0;
    }
    
    static void *extend_heap(size_t words) {
      char *bp;
      size_t size;
    
      /*Allocate an even number of words to maintain alignment*/
      size=(words%2)? (words+1)*WSIZE : words*WSIZE;
      if((long)(bp = mem_sbrk(size)) == -1) return NULL;
    
      /*Initialize free block header/footer and the epilogue header*/
      PUT(HDRP(bp),PACK(size,0));              /*New block header and Free Epilogue*/
      PUT(FTRP(bp),PACK(size,0));              /*New block footer*/
      PUT(HDRP(NEXT_BLKP(bp)),PACK(0,1));      /*New Epilogue header*/
    
      /*Coalesce if the previous block was free*/
      return coalesce(bp);
    }
    
    void mm_free(void *bp){
      size_t size=GET_SIZE(HDRP(bp));
    
      PUT(HDRP(bp),PACK(size,0));
      PUT(FTRP(bp),PACK(size,0));
      coalesce(bp);
    }
    
    static void *coalesce(void *bp){
      size_t prev_alloc=GET_ALLOC(FTRP(PREV_BLKP(bp)));
      size_t next_alloc=GET_ALLOC(HDRP(NEXT_BLKP(bp)));
      size_t size=GET_SIZE(HDRP(bp));
    
      if(prev_alloc && next_alloc) {                 /*Case 1*/
        return bp;
      }
    
      else if(prev_alloc && !next_alloc) {           /*Case 2*/
        size+=GET_SIZE(HDRP(NEXT_BLKP(bp)));
        PUT(HDRP(bp),PACK(size,0));
        PUT(FTRP(bp),PACK(size,0));
      }
    
      else if(!prev_alloc && !next_alloc) {          /*Case 3*/
        size+=GET_SIZE(HDRP(PREV_BLKP(bp)));
        PUT(HDRP(bp),PACK(size,0));
        PUT(HDRP(PREV_BLKP(bp)),PACK(size,0));
        bp = PREV_BLKP(bp);
      }
    
      else {                                         /*Case 4*/
        size+=GET_SIZE(HDRP(PREV_BLKP(bp)))+
          GET_SIZE(FTRP(NEXT_BLKP(bp)));
        PUT(HDRP(PREV_BLKP(bp)),PACK(size,0));
        PUT(FTRP(NEXT_BLKP(bp)),PACK(size,0));
      }
      return bp;
    }
    
    void *mm_malloc(size_t size) {
      size_t asize;                    /*Adjusted block size*/
      size_t extendsize;               /*Amount to extend heap if no fit*/
      char *bp;
    
      /*Ignore spurious requests*/
      if(size == 0) return NULL;
    
      /*Adjust block size to include overhead and alignment reqs.*/
      if(size < DSIZE) asize=2*DSIZE;
      else asize=DSIZE*((size+(DSIZE)+(DSIZE-1))/DSIZE);     /*judge size*/
    
      /*Search the free list for a fit*/
      if((bp = find_fit(asize)) != NULL) {
        place(bp,asize);
        return bp;
      }
    
      /*No fit found.Get more memory and place the block*/
      extendsize = MAX(asize,CHUNKSIZE);
      if((bp = extend_heap(extendsize/WSIZE)) == NULL) return NULL;
    
      place(bp,asize);
      return bp;
    }
    
    static void *find_fit(size_t asize) {
      char *bp = (heap_listp+DSIZE);                           /*get first block*/
      size_t this_alloc=GET_ALLOC(HDRP(NEXT_BLKP(bp)));        /*judge if 0*/
      size_t this_size=GET_SIZE(HDRP(bp));                     /*get size*/
      
      while(!(this_alloc == 0x1 && this_size == 0)) {          /*scan the list*/
        if(this_alloc == 0x0 && this_size >= asize) return bp; /*get the good block*/
        
        bp=NEXT_BLKP(bp);                                      /*get the next one*/
        this_alloc=GET_ALLOC(HDRP(NEXT_BLKP(bp)));             
        this_size=GET_SIZE(HDRP(bp));
      }
      return NULL;                                             /*bad scan*/
    }
    
    static void *place(void *bp,size_t asize){
      size_t old_size=GET_SIZE(HDRP(bp));                      /*save old size*/
      
      if(asize == old_size) {                                  /*same size*/
        PUT(HDRP(bp),PACK(asize,1));
        PUT(FTRP(bp),PACK(asize,1));
      }
    
      else {                                                   /*samller size*/
        size_t rem_size=old_size-asize;                        /*get the remain size*/
        PUT(HDRP(bp),PACK(asize,1));                           /*set the alloc*/
        PUT(FTRP(bp),PACK(asize,1));
        void *next_bp=NEXT_BLKP(bp);
        PUT(HDRP(next_bp),PACK(rem_size,0));                   /*set alloc and size*/
        PUT(FTRP(next_bp),PACK(rem_size,0));
      }
    }

    下面是memlib   注意MAX_HEAP 不要取太大不然开不了

    #define MAX_HEAP (1<<20)
    
    /*Private global variables*/
    
    static char *mem_heap;       /*Points to first byte of heap*/
    static char *mem_brk;        /*Points to last byte of heap plus 1*/
    static char *mem_max_addr;   /*Max legal heap addr plus 1*/
    
    /*
     *mem_init - Initialize the memory system model
     */
    
    void mem_init(void) {
      mem_heap = (char*)malloc(MAX_HEAP);
      mem_brk = (char*)mem_heap;
      mem_max_addr = (char*)(mem_heap + MAX_HEAP);
    }
    
    /*
     *mem_sbrk - Simple model of the sbrk function. Extends the heap 
     *      by incr bytes and returns the start address of the new area.In
     *      this model,the heap cannot be shrunk.
     */
    
    void *mem_sbrk(int incr) {
      char *old_brk = mem_brk;
      
      if((incr < 0) || ((mem_brk + incr) > mem_max_addr)) {
        errno = ENOMEM;
        fprintf(stderr,"ERROR: memsbrk failed. Ran out of memory ...
    ");
        return (void*)-1;
      }
      mem_brk+=incr;
      return (void*)old_brk;
    }

    加上相应的库函数就可以运行了.不过问题是mm_free有没有很好的工作我还没想到很好的方法检验.

  • 相关阅读:
    HDU1883 Phone Cell
    HDU2297 Run
    关于反射的疑惑
    struts2+spring 实例教程
    在.Net 模板页中使用CSS样式
    到底是什么反射,泛型,委托,泛型
    asp.net如何实现删除文件夹及文件内容操作
    学好C#方法
    Web网页安全色谱
    总结一些ASP.NET常用代码
  • 原文地址:https://www.cnblogs.com/tclan126/p/8413499.html
Copyright © 2011-2022 走看看