赞
踩
可变分区管理是属于连续存储管理的实现方法,这种方法按照作业大小划分分区,划分的时间、大小和位置都是动态的,是一种动态分区方法。
以可变分区管理实现内存的动态申请与释放,限定最大分区数和存储空间大小,每次操作后显示分区信息。当申请内存时,从中选取满足要求的空闲区,并划出一个分区;当不满足要求或超出分区数限制时,提示分配失败;当释放内存时,回收相应内存区,并合并成一个新的空闲区。
由我们去实现底层的内存分配机制还是有些困难的,这里只是用c语言实现模拟可变分区管理的这种机制。为了模拟这种机制主要需要实现以下内容:
采用链表的结构存储分区信息,这里可以用空闲和占用两个链表分别存储空闲分区和已分配的分区。当然,如果不想操作那么复杂的话也可以直接用一条链表搞定,只需要在节点定义时多加一个属性来判断分区是否空闲即可。
#define MaxParts 5//定义分区最大数 #define Memaxsize 1024//定义内存大小 typedef struct Part//分区信息 { int startAddress;//开始地址 int length;//分区长度 bool freee;//是否空闲 struct Part *next;//下一个分区 }Part; Part partFirst={0,Memaxsize,true,NULL};//初始化分区链表首项 typedef struct Distribution//分配结果 { bool give;//是否获得分区 Part *part;//分区信息 int errorType;//错误类型 1 分区数过多 2 无足够大的分区 }Distribution;
当由用户提出内存申请时,需要对链表进行查找,找到符合要求的分区分配给用户,分区分配有很多种算法,如下:
for(Part *temp = &partFirst;temp != NULL;temp = temp->next)//遍历内存分区表 { if (temp->freee && temp->length > length)//找到足够大的分区 { if (countPart + 1 > MaxParts) //已经达到最大分区数目,拒绝分配 { errorType = 1; break; } else //可以分配 countPart++; temp->freee = false;//将分区标记为已分配 int tempLength = temp->length; temp->length = length;//分区长度为申请长度 Part * tempNext = temp->next;//新建一个分区节点插入到当前分区节点之后 tempNext = (Part *)malloc(sizeof(Part)); tempNext->startAddress=temp->startAddress + temp->length; tempNext->length=tempLength - length; tempNext->freee=true; tempNext->next=temp->next; temp->next=tempNext;//这些步骤主要是为分割之后剩余的部分新建一个分区插入到分区链中,其中步骤不再赘述注释 disPart = temp; dised = true; break; } else if (temp->freee && temp->length == length)//大小相等直接修改空闲值 { temp->freee = false;//这种情况不需要分割分区,直接分配 disPart = temp; dised = true; break; } if(temp->next==NULL)//没有找到满足大小的分区,返回错误信息 errorType = 2; }
分区释放主要考虑以下四种情况:
for(Part *temp = &partFirst;temp != NULL;temp = temp->next)//遍历找释放分区的前一个分区 { if (i+1 == n && temp->next != NULL) { if (temp->next->next != NULL && temp->next->next->freee == true) //后一个为空闲 { if (temp->freee) //前后都为空闲,合并三个分区 { Part *center = temp->next; Part *right = temp->next->next; Part *tempNext = temp->next->next->next; temp->length += temp->next->length + temp->next->next->length; temp->next = tempNext; free(center); center=NULL; free(right); right=NULL; } else //后面一个为空闲,合并两个分区 { Part *right = temp->next->next; Part *tempNext = temp->next->next->next; temp->next->length += temp->next->next->length; temp->next->next = tempNext; temp->next->freee = true; free(right); right=NULL; } } else //后一个不为空闲 { if (temp->freee) //前一个为空闲,合并两个分区 { Part *center = temp->next; Part *tempNext = temp->next->next; temp->length += temp->next->length; temp->next = tempNext; free(center); center=NULL; } else//前后都不为空,只释放分区 temp->next->freee = true; } freee = true; break; } else if(n==1)//特例判断,释放第一项,仅观察其后一分区是否为空 { if(temp->next->freee)//释放分区并合并 { Part *right = temp->next; Part *tempNext = temp->next->next; temp->length += temp->next->length; temp->next = tempNext; temp->freee = true; free(right); right=NULL; } else//只释放分区 temp->freee = true; freee = true; break; } i++; }
上述已经完成了模拟实现可变分区管理的机制主体部分,适当组织一下交互操作流程即可。
这里给出参考代码:
void Menu() { int selected; int value; Distribution ret; bool quit = false; while (!quit) { printf("可变分区存储管理\n"); printf("1、申请内存\n"); printf("2、释放内存\n"); printf("3、退 出\n"); scanf("%d",&selected); switch (selected) { case 1: printf("请输入申请内存大小:\n"); scanf("%d",&value); ret = requestMe(value); if (ret.give) { printf("\n分配成功.\n"); } else { printf("\n分配失败.\n"); switch(ret.errorType) { case 1: printf("%s.\n", "分区数达到限制"); break; case 2: printf("%s.\n", "没有足够大的分区可以分配"); break; case 0:default:break; } } break; case 2: printf("请输入要释放的分区序号:\n"); scanf("%d",&value); freeMe(value); break; case 3: quit = true; break; default: break; } if(!quit) showMe();//这是一个简单的遍历链表的函数 } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。