⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mm.c

📁 ICS 课程的Lab7
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * mm-naive.c - The fastest, least memory-efficient malloc package. *  * In this naive approach, a block is allocated by simply incrementing  * the brk pointer.  A block is pure payload. There are no headers or footers. * Blocks are never coalesced or reused. Realloc is implemented  * directly using mm_malloc and mm_free. */#include <stdio.h>#include <stdlib.h>#include <assert.h>#include <unistd.h>#include <string.h>#include "mm.h"#include "memlib.h"/* declare mm_check as static */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);/* $begin mallocmacros *//* single word (4) or double word (8) alignment */#define ALIGNMENT 8/* rounds up to the nearest multiple of ALIGNMENT */#define ALIGN(size) (((size) + (ALIGNMENT-1)) & ~0x7)/* Basic constants and macros */#define SIZE_T_SIZE (ALIGN(sizeof(size_t)))#define WSIZE 4          /* word size (bytes) */  #define DSIZE 8          /* doubleword size (bytes) */#define CHUNKSIZE (1<<12)   /* initial heap size (bytes) */#define MAX(x,y)  ((x) > (y)? (x):(y))   /* overhead of header and footer (bytes) *//* Pack a size and allocated bit into a word */#define PACK(size,alloc)  ((size) | (alloc))/* overhead byte size */#define OVERHEAD 8/* Read and write a word at address p */#define GET(p)       (*(size_t *)(p))#define PUT(p,val)   (*(size_t *)(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, compute 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)))#define NEXT(bp)       ((char *)(bp)+WSIZE)/* $end mallocmacros */void *heap_listp=NULL;   /* The global variable is a pointer to the first block */void *header=NULL;       /* The header of the double linked list */void *tail;              /* The tail of the double linked list */int j=0;                 /* The global condition sign *//*  * mm_init - initialize the malloc package. */int mm_init(void){    /* initialize all the global variables*/    header=NULL;                  tail=NULL;               /* set all the pointer to be null */    j=0;                     /* set all the integers to 0 */       /* initialize an start space */    if((heap_listp=mem_sbrk(4*WSIZE))==NULL)        return -1;          /* if get null,return due to false */        PUT(heap_listp,0);      /* alignment padding */        PUT(heap_listp+WSIZE,PACK(OVERHEAD,1));   /* prologue header */         PUT(heap_listp+DSIZE,PACK(OVERHEAD,1));   /* prologue footer */         PUT(heap_listp+WSIZE+DSIZE,PACK(0,1));    /* epilogue header */    heap_listp += DSIZE;       /* Extend the empty heap with a free block of CHUNKSIZE bytes */    if(extend_heap(1<<4)==NULL)        return -1;         /* If error happens,return -1 */        return 0;	           /* Normally exits */}/*  * extend_heap - Extend heap with free block and return its block pointer */static void *extend_heap(size_t words){    void* bp;           /* The return pointer to the new block */    size_t size;        /* The apporiate size of the new block */    /* Allocate an even number of words to maintain alignment */    size=(words%2) ? (words+1)*WSIZE:words*WSIZE;    /* Get a memory space by system call */    if((int)(bp=mem_sbrk(size))<0)          return NULL;    /* Initialize free block header/footer and the epilogue header */    PUT(HDRP(bp),PACK(size,0));    PUT(FTRP(bp),PACK(size,0));    PUT(HDRP(NEXT_BLKP(bp)),PACK(0,1));        /* Coalesce if the previous block was free */    return coalesce(bp);       }/* $end mmextendheap *//* * mm_free - Freeing a block does nothing. */void mm_free(void *ptr){    /* Get the size of the free block */    size_t size=GET_SIZE(HDRP(ptr));    /* Set the mark to be free */    PUT(HDRP(ptr),PACK(size,0));    PUT(FTRP(ptr),PACK(size,0));    coalesce(ptr);             /* coalesce the block to join with others */}/* * mm_realloc - Implemented simply in terms of mm_malloc and mm_free */void *mm_realloc(void *ptr, size_t size){    void *oldptr=ptr;      /* The old pointer pointing to the old block */    void *newptr;          /* The new pointer pointing to the new block */    size_t oldsize;        /* The size of the old block */    size_t newsize;        /* The size of the new block */    void *pre=PREV_BLKP(ptr);   /* The previous block of the old one */    void *next=NEXT_BLKP(ptr);  /* The next block of the old one */    size_t next_size;      /* The size of the next block */    size_t pre_size;       /* The size of the previous block */    size_t prev_alloc=GET_ALLOC(FTRP(pre));   /* The sign of the previous block */    size_t next_alloc=GET_ALLOC(HDRP(next));  /* The sign of the next block */    if(size < 0)           /* If the size smaller than 0,return null */        return NULL;    if(ptr == NULL)        /* If the pointer is null ,malloc a new block */       return  mm_malloc(size);         else if(size == 0)     /* If size is 0,free the old one */    {        mm_free(ptr);        return NULL;    }    else                   /* The normal case */     {        oldsize = GET_SIZE(HDRP(oldptr));   /* Get the old size */        size = ((size+ (DSIZE - 1))/DSIZE)*DSIZE;     /* align the new size */	        newsize =size + DSIZE;     /* add the header and footer size */        if(oldsize>=newsize)       /* If oldsize bigger than new size ,just return */            return oldptr;        else        {            if(prev_alloc && next_alloc)  /* If the prev and next blocks are both allocated */            {                newptr=mm_malloc(size);   /* Malloc a new bigger block */                memcpy(newptr,oldptr,oldsize-DSIZE);  /* copy the data to the aim place */                mm_free(oldptr);          /* free the old block */		                return newptr;            /* return the new pointer */                            }else if(!prev_alloc && next_alloc)  /* If prev is free and the next is allocated */            {                void *pre1=(void *)(GET(pre));   /* Get the previous block */                                void *next1=(void *)(GET(NEXT(pre))); /* Get the next pointer */                                pre_size = GET_SIZE(HDRP(pre));    /* Get the previous block size */                                if(pre_size+oldsize>=newsize)    /* If the two sum is bigger enough */                {                                        PUT(HDRP(pre),PACK(pre_size+oldsize,1));  /* Set the header and footer */                    PUT(FTRP(pre),PACK(pre_size+oldsize,1));		    		    char *temp1=(char *)pre;		    char *temp2=(char *)oldptr;		    int ii;		    for(ii=0;ii<oldsize;ii++)   /* copy the data to the new block */		    {			*temp1=*temp2;			 temp1++;			 temp2++;		    }		     /* If the pre in the list is null and next is null too */                    if(pre1==NULL && next1==NULL)                        tail=header=NULL;    		    /* If the pre in the list is not null but the next is null */                    else if(pre1!=NULL && next1==NULL)                    {                        PUT(NEXT(pre1),(int)NULL); /* Set the next of the prev */                        tail=pre1;              /* Set the tail */                    }		    /* If the pre in the list is null but the next is not null */                    else if(pre1==NULL && next1!=NULL)                    {                        PUT(next1,(int)NULL);   /* Set the next */                        header=next1;           /* Set the header */                    }		    /* If the pre in the list is not null and so is the next */                    else if(pre1!=NULL && next1!=NULL)                    {                        PUT(NEXT(pre1),(int)next1);  /* set the next of the pre */                        PUT(next1,(int)pre1);        /* set the pre of the next*/                    }                  return pre;                  }                else  /* The total size is not big enough */                {		    newptr=mm_malloc(size);     /* malloc a new block big enough */		    memcpy(newptr,oldptr,oldsize-DSIZE);  /* copy the data */		    mm_free(oldptr);            /* free the old block */		    return newptr;              /* return the new block */                }		/* The prevoius is allocated but the next block is not allocated */            }else if(prev_alloc && !next_alloc)            {                void *pre2=(void *)(GET(next));   /* The next of the block */                void *next2=(void *)(GET(NEXT(next))); /*The next of the next of the block*/                                 next_size=GET_SIZE(HDRP(next));   /* Get the size of the next */				// If the total size is big enough */                if(next_size+oldsize>=newsize)                {		    /* Set the block sign */                    PUT(HDRP(oldptr),PACK(next_size+oldsize,1));                    PUT(FTRP(oldptr),PACK(next_size+oldsize,1));		    /* If the pre is null and next is null too */                    if(pre2==NULL && next2==NULL)                        tail=header=NULL;		    /* If the pre in the list is not null but the next is null */                    else if(pre2!=NULL && next2==NULL)                    {                        PUT(NEXT(pre2),(int)NULL);                        tail=pre2;                    }		    /* If the pre in the list is null but the next is not null */                    else if(pre2==NULL && next2!=NULL)                    {                        PUT(next2,(int)NULL);                        header=next2;                    }                    /* If the pre in the list is null and the next is null */                    else if(pre2!=NULL && next2!=NULL)                    {                        PUT(NEXT(pre2),(int)next2);                        PUT(next2,(int)pre2);                    }                    return oldptr;    /* return the old block pointer */                }else                {		    newptr=mm_malloc(size);   /* malloc a new block */		    memcpy(newptr,oldptr,oldsize-DSIZE); /* copy the data to the aim */		    mm_free(oldptr);          /* free the old block */		    return newptr;            /* return the new block pointer */                }            }            else            {                pre_size=GET_SIZE(HDRP(pre));  /* the size of the pre block */                next_size=GET_SIZE(HDRP(next));/* the size of the next block */		                void *pre1=(void *)(GET(pre)); /* the pre pointer */                void *next2=(void *)(GET(NEXT(next)));  /* the next pointer */                if((oldsize+pre_size)>=newsize) /* If the total size is enough */                {                    PUT(HDRP(pre),PACK(pre_size+oldsize,1)); /* Set the sign */                    PUT(FTRP(pre),PACK(pre_size+oldsize,1));		    		    char *temp1=(char *)pre;		    char *temp2=(char *)oldptr;		    int ii;		    for(ii=0;ii<oldsize;ii++)   /* copy the data to the new block */		    {			*temp1=*temp2;			temp1++;			temp2++;		    }		    /* The pre in the list is null */		    if(pre1==NULL)                     {                         PUT(next,(int)NULL);        /* set the header */                         header=next;                     }		    else   /* The pre is not null */                     {                         PUT(NEXT(pre1),(int)next); /* set the next */                         PUT(next,(int)pre1);                     }                     		    return pre;       /* return the pre pointer */                }                                        		/* The sum of the current and next is enough */                else if((oldsize+next_size)>=newsize)                { 		    /* Set the sign */                    PUT(HDRP(oldptr),PACK(next_size+oldsize,1));                    PUT(FTRP(oldptr),PACK(next_size+oldsize,1));                    if(next2==NULL)   /* If next is null */                    {                        PUT(NEXT(pre),(int)NULL); /* set the next */                        tail=pre;                 /* set the tail */                    }else                    {                        PUT(NEXT(pre),(int)next2); /* set the next of the pre */                        PUT(next2,(int)pre);                    }                                        return oldptr;   /* return the old block pointer */                }                                /* The total size of the three blocks are big enough */                else  if(pre_size+oldsize+next_size>=newsize)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -