• CSAPP 六个重要的实验 lab5


    CSAPP  && lab5



    实验指导书:

    http://download.csdn.net/detail/u011368821/7951657

    实验材料:

    http://download.csdn.net/detail/u011368821/8019293


    搞定这个实验还是要看一下曾经的笔记,再复习一下block的组织方式。仅仅看link里面第11节,动态内存分配的部分就能够了

    http://blog.csdn.net/cinmyheart/article/details/38136375

    然后看看对block的探測性学习

    http://blog.csdn.net/cinmyheart/article/details/38174421



                      The only file you will modify and turn in is mm.c.


                      Your dynamic storage allocator will consist of the following three functions (and several helper functions), which are declared in mm.h and defined in mm.c:

    int mm_init(void);
    void* mm_malloc(size_t size);
    void mm_free(void* ptr);


                   Your job is to complete this implementation by filling out mm_malloc() and mm_free(). 




    任务就是利用下面现有的API去补全mm_malloc()和mm_free()

    Provided Code


                     We define a BlockInfo struct designed to be used as a node in a doubly­linked explicit free list, and the following functions for manipulating free lists:


    BlockInfo* searchFreeList(int reqSize): returns a block of at least the requested size if one exists (and NULL otherwise).
    void insertFreeBlock(BlockInfo* blockInfo): inserts the given block in the free list in LIFO manner.
    void removeFreeBlock(BlockInfo* blockInfo): removes the given block from the free list.
    


                     In addition, we implement mm_init and provide two helper functions implementing important parts of the allocator:


    void requestMoreSpace(int incr): enlarges the heap by incr bytes (if enough memory is available on the machine to do so).
    void coalesceFreeBlock(BlockInfo* oldBlock): coalesces any other free blocks adjacent in memory to oldBlock into a
    single new large block and updates the free list accordingly.


    这里free list的实现介绍: 这里须要说明一下的就是header处于低地址,footer处于高地址. 这里说明的原因是由于实现的时候会有指针的加减,注意一下就是了 :-)

    sizeAndTags中记录的size信息是整个block的大小。包含了struct BlockInfo结构体的大小


    论证: 观察struct BlockInfo结构体在内存中的分布


    正是依据内存布局的特点,这里blockCursor仅仅想当前block头的时候减去一个WORD_SIZE会得到什么?

    前一个block的footer 即boundary tag,由此获知当前block的前一个block的大小



    My answer:

    /* Allocate a block of size size and return a pointer to it. */
    void* mm_malloc (size_t size) {
      size_t reqSize;
      BlockInfo * ptrFreeBlock = NULL;
      BlockInfo * ptrNextBlock = NULL;
      size_t blockSize;
      size_t precedingBlockUseTag;
      size_t* ptrNextBlockFooter = NULL; 
    
      // Zero-size requests get NULL.
      if (size == 0) {
        return NULL;
      }
    
      // Add one word for the initial size header.
      // Note that we don't need to boundary tag when the block is used!
      size += WORD_SIZE;
      if (size <= MIN_BLOCK_SIZE) {
        // Make sure we allocate enough space for a blockInfo in case we
        // free this block (when we free this block, we'll need to use the
        // next pointer, the prev pointer, and the boundary tag).
        reqSize = MIN_BLOCK_SIZE;
      } else {
        // Round up for correct alignment
        reqSize = ALIGNMENT * ((size + ALIGNMENT - 1) / ALIGNMENT);
      }
    
      // Implement mm_malloc.  You can change or remove any of the above
      // code.  It is included as a suggestion of where to start.
      // You will want to replace this return statement...
    
      ptrFreeBlock =  searchFreeList(reqSize);
    
      if(!ptrFreeBlock)
      {
    	requestMoreSpace(reqSize);
    	ptrFreeBlock = searchFreeList(reqSize);
      }
      
      blockSize = SIZE(ptrFreeBlock->sizeAndTags);
    
      if(blockSize < reqSize + MIN_BLOCK_SIZE)
      {
    	reqSize = blockSize;
      }
    
      precedingBlockUseTag = ptrFreeBlock->sizeAndTags & TAG_PRECEDING_USED;
      ptrFreeBlock->sizeAndTags = reqSize | precedingBlockUseTag | TAG_USED;
    
      ptrNextBlock = (BlockInfo*)UNSCALED_POINTER_ADD(ptrFreeBlock,reqSize);
    
      if(reqSize != blockSize)
      {
    	ptrNextBlock->sizeAndTags = (blockSize - reqSize) | TAG_PRECEDING_USED;
    
    	ptrNextBlockFooter = (size_t *)UNSCALED_POINTER_ADD(ptrFreeBlock,blockSize - WORD_SIZE);
    
    	(*ptrNextBlockFooter) = ptrNextBlock->sizeAndTags;
    
    	insertFreeBlock(ptrNextBlock);
      }
      else
      {
       	ptrNextBlock->sizeAndTags = ptrNextBlock->sizeAndTags | TAG_PRECEDING_USED;
    
    	ptrNextBlockFooter = (size_t*)UNSCALED_POINTER_ADD(ptrNextBlock,SIZE(ptrNextBlock->sizeAndTags) - WORD_SIZE);
    
    	(*ptrNextBlockFooter) = ptrNextBlock->sizeAndTags;
      }
      removeFreeBlock(ptrFreeBlock);
      
    
      return (void*)UNSCALED_POINTER_ADD(ptrFreeBlock,WORD_SIZE); 
    }
    
    /* Free the block referenced by ptr. */
    void mm_free (void *ptr) {
      size_t payloadSize; 
      size_t blockSize;
      BlockInfo * blockInfo;
      BlockInfo * followingBlock;
    
      // Implement mm_free.  You can change or remove the declaraions
      // above.  They are included as minor hints.
    
      BlockInfo* prev_block = NULL;
      BlockInfo* next_block = NULL;
    
      blockInfo = (BlockInfo*)UNSCALED_POINTER_SUB(ptr,WORD_SIZE);
      followingBlock = (BlockInfo *)UNSCALED_POINTER_ADD(blockInfo,blockInfo->sizeAndTags);
    
      blockSize = SIZE(blockInfo->sizeAndTags);
      payloadSize = blockSize - WORD_SIZE;
      blockInfo->sizeAndTags = blockInfo->sizeAndTags & ~TAG_USED;
      *(size_t *)UNSCALED_POINTER_ADD(blockInfo,payloadSize) = blockInfo->sizeAndTags;
      followingBlock->sizeAndTags = followingBlock->sizeAndTags & ~TAG_PRECEDING_USED;
    
      if(followingBlock->sizeAndTags & TAG_USED == 0)
      {
          *(size_t *)UNSCALED_POINTER_ADD(followingBlock,SIZE(followingBlock->sizeAndTags) - WORD_SIZE) = followingBlock->sizeAndTags;
      }
    
      insertFreeBlock(blockInfo);
      coalesceFreeBlock(blockInfo);
    
    }




    最后执行./mdriver 

    会有一下输出





    题外话,追究这个malloc实现的话....事实上它就是基于已经有的stdlib.h已经有的malloc而实现的,介绍的是实现原理,利用双向链表



    后面的额外练习表示没有耐心了,对于realloc...


    到此,CSAPP的lab临时告一段落,以后还会峰峰补补的去更新 :-)

    假设对这六个lab感兴趣,欢迎邮箱联系交流讨论

    jasonleaster@gmail.com 





    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    【实战HTML5与CSS3】用HTML5和CSS3制作页面(上)
    VS2008中应用自动属性报错的解决方法
    Win7中启动多个Dropbox实例
    编写WCF服务时右击配置文件无“Edit WCF Configuration”远程的解决办法
    ASP.NET WebForm也玩强类型URL调用之二:PageMethods的基本使用
    VS中折叠/展开所有项目的宏
    让多线程调试更简单的宏代码FreezeThawThreads
    Sql Server 中修改系统表的方法总结
    Python学习之一:语言的选择以及WingIDE破解
    ASP.NET WebForm也玩强类型URL调用之一:PageMethods简介
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4724840.html
Copyright © 2020-2023  润新知