CSAPP实验5:malloc lab

前言

这个实验想法还是十分清晰的,但是我写了几次都直接错误了,然后bug也不知道到底是哪里出现了问题,最后就只好参考别人的了。
参考博客:实验5:malloc lab

代码



#include "mm.h"
#include "memlib.h"

team_t team = {
     /* Team name */
    "XXXXXX",
    /* First member's full name */
    "yzf",
    /* First member's email address */
    "@Fd",
    /* Second member's full name (leave blank if none) */
    "",
    /* Second member's email address (leave blank if none) */
    ""
};
#define ALIGNMENT 8

/* rounds up to the nearest multiple of ALIGNMENT */
#define ALIGN(size) (((size) + (ALIGNMENT-1)) & ~0x7)


#define SIZE_T_SIZE (ALIGN(sizeof(size_t)))

#define WSIZE 4
#define DSIZE 8
#define CHUNKSIZE (1<<12) /* Extend heap by this amount (bytes) */
#define MINBLOCKSIZE 16

#define MAX(x, y) ((x) > (y) ? (x) : (y))
#define PACK(size, alloc) ((size) | (alloc)) /* Pack a size and allocated bit into a word */

#define GET(p) (*(unsigned int *)(p)) /* read a word at address p */
#define PUT(p, val) (*(unsigned int *)(p) = (val)) /* write a word at address p */

#define GET_SIZE(p) (GET(p) & ~0x7) /* read the size field from address p */
#define GET_ALLOC(p) (GET(p) & 0x1) /* read the alloc field from address p */

#define HDRP(bp) ((char*)(bp) - WSIZE) /* given block ptr bp, compute address of its header */
#define FTRP(bp) ((char*)(bp) + GET_SIZE(HDRP(bp)) - DSIZE) /* given block ptr bp, compute address of its footer */

#define NEXT_BLKP(bp) ((char*)(bp) + GET_SIZE(HDRP(bp))) /* given block ptr bp, compute address of next blocks */
#define PREV_BLKP(bp) ((char*)(bp) - GET_SIZE((char*)(bp)-DSIZE)) /* given block ptr bp, compute address of prev blocks */
static char* heap_listp;
static void* extend_heap(size_t size);
static void* coalesce(void *bp);
static void* find_fit(size_t asize);
static void split_block(void* bp, size_t asize);
static void place(void* bp, size_t asize);
int mm_init(void);
void *mm_malloc(size_t size);
void mm_free(void *bp);
void *mm_realloc(void *ptr, size_t size);

/*
 * extend heap by words * word(4 bytes)
 */
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)); //free block header
    PUT(FTRP(bp), PACK(size, 0)); //free block footer
    PUT(HDRP(NEXT_BLKP(bp)), PACK(0, 1)); // new epilogue header

    return coalesce(bp); //coalesce if the previous block was free
       
}

/*
 * coalesce
 */
static void* coalesce(void *bp)
{
      size_t pre_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(pre_alloc&&next_alloc)return bp;
       else if(!pre_alloc&&next_alloc){
            size+=GET_SIZE(FTRP(PREV_BLKP(bp)));
            PUT(HDRP(PREV_BLKP(bp)),PACK(size,0));
            PUT(FTRP(bp),PACK(size,0));
            return PREV_BLKP(bp);
       }else if(pre_alloc&&!next_alloc){
            size+=GET_SIZE(HDRP(NEXT_BLKP(bp)));
            PUT(HDRP(bp),PACK(size,0));
            PUT(FTRP(bp),PACK(size,0));
            return bp;
       }else {
            size+=GET_SIZE(FTRP(PREV_BLKP(bp)))+GET_SIZE(HDRP(NEXT_BLKP(bp)));
            PUT(HDRP(PREV_BLKP(bp)),PACK(size,0));
            PUT(FTRP(PREV_BLKP(bp)),PACK(size,0));
            return PREV_BLKP(bp);
       }
}

/*
 * find_fit - use first fit strategy to find an empty block.
 */
static void* find_fit(size_t asize)
{
       char*listp;
       for(listp=heap_listp;GET_SIZE(HDRP(listp));listp=NEXT_BLKP(listp)){
           size_t alloc=GET_ALLOC(HDRP(listp));
           size_t size=GET_SIZE(HDRP(listp));
           if(!alloc&&asize<=size){
               return listp;
           }
       }
       return NULL;
}

/*
 * split_block
 */
static void split_block(void* bp, size_t asize)
{
       size_t size = GET_SIZE(HDRP(bp));

    if ((size - asize) >= MINBLOCKSIZE)
    {
        PUT(HDRP(bp), PACK(asize, 1));
        PUT(FTRP(bp), PACK(asize, 1));
        bp = NEXT_BLKP(bp);
        PUT(HDRP(bp), PACK(size-asize, 0));
        PUT(FTRP(bp), PACK(size-asize, 0));
    }
}

/*
 * place - Place the request block at the beginning of the free block, 
 *         and only split if the remaining part is equal to or larger than the size of the smallest block
 */
static void place(void* bp, size_t asize)
{
    size_t size = GET_SIZE(HDRP(bp));
    PUT(HDRP(bp), PACK(size, 1));
    PUT(FTRP(bp), PACK(size, 1));

    split_block(bp, asize);
}

/* 
 * mm_init - initialize the malloc package.
 */
int mm_init(void)
{
    size_t *bp;
    if((bp=mem_sbrk(4*WSIZE))==(void*)-1){
        return -1;
    }
    PUT(heap_listp,0);
    PUT(heap_listp+WSIZE,PACK(DSIZE,1));
    PUT(heap_listp+2*WSIZE,PACK(DSIZE,1));
    PUT(heap_listp+3*WSIZE,PACK(0,1));
    heap_listp+=2*WSIZE;
    next_listp=heap_listp;
    if((bp=extend_heap(CHUNKSIZE/WSIZE))==NULL)return -1;
    return 0;
}

/* 
 * mm_malloc - Allocate a block by incrementing the brk pointer.
 *     Always allocate a block whose size is a multiple of the alignment.
 */
void *mm_malloc(size_t size)
{
    size_t *bp;
      size_t asize,extendsize;
      if(size==0)return NULL;
     if (size <= DSIZE)
        asize = 2*DSIZE;
     else
        asize = DSIZE * ((size + (DSIZE) + (DSIZE - 1)) / DSIZE);
     if((bp=find_fit(asize))!=NULL){
         place(bp,asize);
         return bp;
     }
     extendsize=MAX(asize,CHUNKSIZE);
     if((bp=extend_heap(extendsize/WSIZE))==NULL)return NULL;
     place(bp,asize);
     return bp;
}

/*
 * mm_free - Freeing a block does nothing.
 */
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);
}

/*
 * mm_realloc - Implemented simply in terms of mm_malloc and mm_free
 */
void *mm_realloc(void *ptr, size_t size)
{
    void *oldptr = ptr;
    void *newptr;
    size_t copySize;

    newptr = mm_malloc(size);
    if (newptr == NULL)
      return NULL;
    size = GET_SIZE(HDRP(oldptr));
    copySize = GET_SIZE(HDRP(newptr));
    if (size < copySize)
      copySize = size;
    memcpy(newptr, oldptr, copySize-WSIZE);
    mm_free(oldptr);
    return newptr;
}

实验结果

在这里插入图片描述

Malloc Lab是一个实验项目,要求我们实现一个动态内存分配器,使其具有与标准C库中的malloc、free、realloc函数相同的功能。我们需要自行定义块的空间结构,并实现find_fit函数和place函数,这两个函数都涉及到指针的操作,需要特别注意,以避免出现BUG。 在实现动态内存分配器时,我们需要考虑以下几个方面: 1. 内存块的分配和释放:我们需要实现malloc和free函数,前者用于分配内存块,后者用于释放内存块。 2. 内存块的合并:当一个内存块被释放时,我们需要将其与相邻的空闲块合并,以便后续的内存分配。 3. 内存块的查找:在分配内存块时,我们需要查找一个合适的空闲块,以满足用户的需求。 以下是一个简单的动态内存分配器的实现,仅供参考: ```c /* 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 amount (bytes) */ /* Pack a size and allocated bit into a word */ #define PACK(size, alloc) ((size) | (alloc)) /* Read and write a word 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, 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))) /* Global variables */ static char *heap_listp = 0; /* Function prototypes for internal helper routines */ 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); /* * mm_init - Initialize the memory manager */ 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; } /* * mm_malloc - Allocate a block with at least size bytes of payload */ 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); /* 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; } /* * mm_free - Free a block */ 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); } /* * mm_realloc - naive implementation of mm_realloc */ void *mm_realloc(void *ptr, size_t size) { void *newptr; size_t copySize; /* If size == 0 then this is just free, and we return NULL. */ if (size == 0) { mm_free(ptr); return 0; } /* If oldptr is NULL, then this is just malloc. */ if (ptr == NULL) { return mm_malloc(size); } newptr = mm_malloc(size); /* If realloc() fails the original block is left untouched */ if (!newptr) { return 0; } /* Copy the old data. */ copySize = GET_SIZE(HDRP(ptr)); if (size < copySize) { copySize = size; } memcpy(newptr, ptr, copySize); /* Free the old block. */ mm_free(ptr); return newptr; } /* * extend_heap - Extend heap with free block and return its block pointer */ 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)); /* Free block header */ PUT(FTRP(bp), PACK(size, 0)); /* Free block footer */ PUT(HDRP(NEXT_BLKP(bp)), PACK(0, 1)); /* New epilogue header */ /* Coalesce if the previous block was free */ return coalesce(bp); } /* * coalesce - Boundary tag coalescing. Return ptr to coalesced block */ 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(FTRP(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)); bp = PREV_BLKP(bp); } return bp; } /* * find_fit - Find a fit for a block with asize bytes */ static void *find_fit(size_t asize) { void *bp; for (bp = heap_listp; GET_SIZE(HDRP(bp)) > 0; bp = NEXT_BLKP(bp)) { if (!GET_ALLOC(HDRP(bp)) && (asize <= GET_SIZE(HDRP(bp)))) { return bp; } } return NULL; /* No fit */ } /* * place - Place block of asize bytes at start of free block bp * and split if remainder would be at least minimum block size */ static void place(void *bp, size_t asize) { size_t csize = GET_SIZE(HDRP(bp)); if ((csize - asize) >= (2*DSIZE)) { PUT(HDRP(bp), PACK(asize, 1)); PUT(FTRP(bp), PACK(asize, 1)); bp = NEXT_BLKP(bp); PUT(HDRP(bp), PACK(csize-asize, 0)); PUT(FTRP(bp), PACK(csize-asize, 0)); } else { PUT(HDRP(bp), PACK(csize, 1)); PUT(FTRP(bp), PACK(csize, 1)); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值