当前位置: 代码迷 >> 综合 >> Malloc Lab要点与收货
  详细解决方案

Malloc Lab要点与收货

热度:140   发布时间:2023-09-29 15:23:33.0

源代码提交到了CSDN上,源代码中总共提供了三种方法,一种是课程自带的,一种是高分方法,还有一种是我自己融合前两种方法写的。

主要参考了https://www.cnblogs.com/liqiuhao/p/8252373.html这篇博客写的

这里主要把课程自带的方法和高分方法的思想主要说一下。

1,课程自带的方法

课程自带的方法中使用了两种方法,最基础的一种是使用了隐式空闲列表+首次适配(遍历寻找第一个合适的空闲块)的方法,得分最低,但也是最简单的方法。

隐式空闲列表的空闲块就是只有头部和脚部,见CSAPP的595页。

主要函数思路解析

mm_realloc中一般情况就是采用直接用mm_malloc函数开辟一块大小为size的新空间,然后将原来ptr指针的内容直接复制过去。

mm_malloc中就是找到合适的空闲块,并返回,其中找到合适空闲块的函数find_fit就是遍历整个可用栈空间,找到的第一个合适的空闲区域就返回该指针。

coalesce是合并空闲块,就是查看当前块前后是否有空闲块,如果有就合并,在扩展完空闲块以及释放完空闲块以后会调用

extend_heap扩展空闲块

place将空闲块改变为分配块,如果有多余的,就把剩下的变为空闲块。

课程自带的第二种方法大体上差不多,但是多了一个rover指针,这个指针一般指向上一次操作被分配的块上,在函数find_fit中,也就是下一次分配时,就是从rover指针处开始遍历找寻合适的空闲块,如果没有,再从头开始遍历到rover指针处。这样分配合适得多,因为每次扩展栈空间,都是扩展一大块,然后在这个空间中切分空闲块,所以上一次被分配的块后面大概率有空闲块。

 

2.高分方法

高分方法是采用的显式空闲列表+分离适配方法。

显式空闲列表就是在空闲块处除了头部和脚部以外,还有前驱指针和后继指针,分别指向前一个空闲块和后一个空闲块,见CSAPP的603页。

分离适配就是维护一个空闲列表数组,将数组中每个元素分为{1}{2}{3~4}{5~8}...{1025~2048}... 等等。根据空闲列表的大小,挂到对应的数组下面去,并且每个数组下面挂载的空闲块是按有小到大的顺序排列的。所以在这个程序中会多出两个空闲块链表操作的函数。

主要函数思路解析(与课程函数不一样的地方)

mm_realloc中不是直接分配size大小块然后复制了,而是先查看该ptr指向块后面有没有足够的空闲块,如果有就不需要复制,直接把后面的空闲块拿来用即可,如果没有再用mm_malloc分配块然后复制过去的操作。

mm_malloc中找到合适空闲块的方法是直接根据size找到对应的空闲列表数组中的位置,然后在该位置处由小到大找到适合自己的空闲块。

coalesce合并空闲块的思想和课程一样

extend_heap扩展空闲块的思想也和课程的一样

place中分配空闲块运用一种方法来减少外部碎片,主要思想就是因为每次扩展空闲块时都是采用一次扩展一大块,然后慢慢切分的方式,所以在分配时根据所需size大小,设定一个临界值,如果大于这个临界值就放后边,小于这个临界值就放前边,大概思路就是把小的分配到一起,然后把大的也分配到一起。

具体细节可以查看一下代码和参考博客

代码理解中碰到的难点

1.注意在修改块头部的值的时候,整个块的尺寸就会改变,所以在修改头部信息时,后面的宏定义一定要小心

2.注意指针的使用,尤其是在高分方法中,PRED_PTR和SUCC_PTR得到的是指向本块中前驱和后继指针存放地址的指针

而PRED和SUCC得到的是前驱指针指向的上一块空闲块的块指针,以及后继指针指向的下一块空闲块的块指针。

3.高分方法中前驱指针和后继指针指向的刚好和我方法中的相反,就我认为前驱指针指向尺寸小于等于自己的空闲块,后继指针指向尺寸大于等于自己的空闲块,而高分方法相反

 

 

  相关解决方案