百度面试题:
给定一块内存,大小为1M,现有一些内存请求序列1K、2K、4K、10K........
要求模拟实现new/delete内存分配过程。
对应题目如下:
假设初始态下,可用内存空间为640K,并有下列请求序列,请分别用首次适应算法和最佳适应算法
为作业分配和回收内存块,并显示出每次分配和回收后的空闲分区链的情况来以及内存占用情况图。
作业1申请130K
作业2申请60K
作业3申请100k
作业2释放60K
......
一、算法的基本思想
根据题目要求,使用首次适应算法和最佳适应算法分别实现内存的动态分区,因此说明一下这两种算法的基本思想:
首先,维护一个空闲分区链表,初始时链表只有一个节点就是整个内存块,在一系列的内存分配与释放之后,分区链表呈现一种空闲与占用交替的状态,一下讨论的时候,针对的就是分区链表普遍的状态的时候。链表结构如下:
struct SubAreaNode
{
int address; //分区起始地址
int size; //分区大小
int state; //分区状态(0,1)两个标记
int taskNo; //记录作业号
SubAreaNode *prior; //分区的前向指针 前驱
SubAreaNode *nexr; //分区的后继指针
}
使用最佳匹配的时候还要开辟一个负责的指针数组,负责存储空闲节点,针对空闲节点指针所指向的节点的 size 大小进行排序。
说明:分区状态 1 表示占用,0表示空闲。
算法思想如下:
(1)为任务分配内存空间的思想
2、最佳适应算法的空闲链是按照空闲块的大小为序、所有空闲区按容量从小到大的顺序形成空闲分区链。在进行内存分配时候,它在满足需要的前提下,尽量分配最小的空闲块,这样每次查找分配时,从链首开始查找,第一次找到的能满足要求的必然的最佳的,若空闲空间大小与要分配的大小相同时,可直接将其状态改为1即可,若有剩余,则将剩余空闲空间重新划分为一个空闲区,然后根据空闲区的大小对链表进行重新排序,这里对空闲分区大小排序采用了快速排序算法。
(2) 已经执行完的任务释放内存空间思想
最佳适应算法分区回收时,因为它的空闲分区链是按照空间大小排列的,因此不仅要看要释放分区前后是否为空闲,还要判断其地址是否前后相接,若地址不相接,则即使要释放分区前后均为空闲区,也不能进行合并,而且每次释放后要根据释放空间的大小对链表进行重新排序,同样采用快速排序算法进行重新排序。
二、通用算法分配内存
通用算法分配内存原理是首先判断申请内存的大小能否在空闲分区中找到适合的,如果找到分两种情况,一是刚好大小一致,二是空闲分区比申请内存大小大,则需要划分空闲分区,剩余的空间为新的分区。
三、首次算法回收内存
四、最佳算法回收内存
最佳算法回收内存主要是实现对内存回收,关键点是根据地址判断前后分区有否空闲,如果有需要合并。在回收后,需要重新排序空闲分区。
五、空闲分区的重新排序
空闲分区的重新排序,需要定义一个空闲分区指针数组,一个空闲分区的空间大小数组,然后调用快速排序函数,根据空间大小进行排序,排序完成后,空闲分区指针数组相应也进行了重新排序,接着是根据指针数组对原来的空闲分区链表排序。
六、快速排序
快速排序是在待排序n个记录中任取一个作为“基准”,将其余记录分为两组,第一组中各记录的值均小于或等于基准的值,第二组中各记录的值均大于或等于基准的值。对所分成两组分别重复上述方法,直到所有记录排在合适位置上。
Parr[]是空闲分区链表指针数组,arr[]是记录每个分区空间大小的整形数组。所以使用快速算法对每个分区空间大小排序,排序的同时也相应调整空闲分区链表指针的先后顺序,这样在排序后,可以利用Parr[]对原来的分区链表进行重新定义。
七、执行截图:
附注:完整程序代码查看地址: http://blog.csdn.net/raymentblog/article/details/6173073
转自:http://blog.sina.com.cn/s/blog_4deeda250100pf4z.html
同时参考:http://hi.baidu.com/avatar_lei/item/58b2ab11f1ed2d4e3b176efb