一:最佳适应算法和首次适应算法
#include<iostream>
#include<stdlib.h>using namespace std;
#define Free 0 //空闲状态
#define Busy 1 //已用状态
#define OK 1 //完成
#define ERROR 0 //出错
#define MAX_length 640 //最大内存空间为640KB
typedef int Status;
typedef struct freearea//定义一个空闲区说明表结构
{
int ID; //分区号
long size; //分区大小
long address; //分区地址
int state; //状态
}ElemType;
//---------- 线性表的双向链表存储结构 ------------
typedef struct DuLNode //double linked list
{
ElemType data;
struct DuLNode *prior; //前趋指针
struct DuLNode *next; //后继指针
}DuLNode, *DuLinkList;
DuLinkList block_first; //头结点
DuLinkList block_last; //尾结点
Status alloc(int);//内存分配
Status free(int); //内存回收
Status First_fit(int, int);//首次适应算法
Status Best_fit(int, int); //最佳适应算法
void show();//查看分配
Status Initblock();//开创空间表
Status Initblock()//开创带头结点的内存空间链表
{
block_first = (DuLinkList)malloc(sizeof(DuLNode));
block_last = (DuLinkList)malloc(sizeof(DuLNode));
block_first->prior = NULL;
block_first->next = block_last;
block_first->data.state = 3;
block_first->data.size = 0;
block_last->prior = block_first;
block_last->next = NULL;
block_last->data.address = 0;
block_last->data.size = MAX_length;
block_last->data.ID = 0;
block_last->data.state = Free;
return OK;
}
//----------------------- 分 配 主 存 -------------------------
Status alloc(int ch)
{
int ID, request;
cout << "请输入作业(分区号(整数)):";
cin >> ID;
cout << "请输入需要分配的主存大小(单位:KB):";
cin >> request;
if (request<0 || request == 0)
{
cout << "分配大小不合适,请重试!" << endl;
return ERROR;
}
if (ch == 2) //选择最佳适应算法
{
if (Best_fit(ID, request) == OK) cout << "分配成功!" << endl;
else cout << "内存不足,分配失败!" << endl;
return OK;
}
else //默认首次适应算法
{
if (First_fit(ID, request) == OK) cout << "分配成功!" << endl;
else cout << "内存不足,分配失败!" << endl;
return OK;
}
}
//------------------ 首次适应算法 -----------------------
Status First_fit(int ID, int request)//传入作业名及申请量
{
DuLNode *p = block_first->next;
//请在此处添加为作业申请新空间且初始化的代码
//请在此处完成首次适应算法的代码,分两种情况:有大小恰好合适的空闲块和有空闲块能满足需求且有剩余。
//注意函数返回值。
DuLinkList block = (DuLinkList)malloc(sizeof(DuLNode));
memset(block, 0, sizeof(DuLNode));
block->data.ID = ID;
block->data.size = request;
block->data.state = Busy;
while (p)
{
if (p->data.state == Free && p->data.size >= request)
{
if ((p->data.size - request) > 1)
{
block->data.address = p->data.address;
p->data.address = p->data.address + request;
p->data.size = p->data.size - request;
p->prior->next = block;
block->next = p;
block->prior = p->prior;
p->prior = block;
return OK;
}
else
{
p->data.ID = ID;
p->data.state = Busy;
free(block);
return OK;
}
}
p = p->next;
}
free(block);
return ERROR;
}
//-------------------- 最佳适应算法 ------------------------
Status Best_fit(int ID, int request)
{
//请在此处添加为作业申请新空间且初始化的代码
DuLinkList block = (DuLinkList)malloc(sizeof(DuLNode));
memset(block, 0, sizeof(DuLNode));
block->data.ID = ID;
block->data.size = request;
block->data.state = Busy;
DuLNode *p = block_first->next;
DuLNode *q = NULL; //记录最佳插入位置
int i = 0;
int num = 0;
DuLNode *q1 = NULL;
while (p)
{
if (p->data.state == Free && p->data.size >= request)
{
if (num == 0)
{
q = p;
i = q->data.size - request;
}
else if (p->data.size - request < i)
{
q = p;
i = q->data.size - request;
}
num++;
}
p = p->next;
}
//请在此处完成最佳适应算法的代码,重点:要查找到最小剩余空间的分区,即最佳插入位置
if (q == NULL) return ERROR;//没有找到空闲块
else
{
//请插入找到了最佳位置并实现内存分配的代码!
if ((q->data.size - request) > 1)
{
block->data.address = q->data.address;
q->data.address = q->data.address + request;
q->data.size = q->data.size - request;
block->next = q;
block->prior = q->prior;
q->prior->next = block;
q->prior = block;
return OK;
}
else
{
q->data.ID = ID;
q->data.state = Busy;
free(block);
return OK;
}
}
}
//----------------------- 主 存 回 收 --------------------
Status free(int ID)
{
DuLNode *p = block_first->next;
DuLNode *p1 = NULL;
while (p)
{
if (p->data.ID == ID)
{
p->data.state = Free;
p->data.ID = Free;
cout << "内存块找到,准备回收!" << endl;
if (p->next == NULL){
if ((p->prior->data.state == Free) && (p->prior->data.address + p->prior->data.size == p->data.address))
{
p->prior->data.size += p->data.size;
p->prior->next = NULL;
free(p);
}
cout << "内存块为最后一块!" << endl;
break;
}
//请在此处添加其他情况的回收的代码,主要包括要回收的分区与前面的空闲块相连或与后面的空闲块相连,或者与前后空闲块相连等。
if ((p->next->next == NULL) && (p->next->data.state == Free) && (p->data.address + p->data.size == p->next->data.address))
{
p->data.size += p->next->data.size;
free(p->next);
p->next = NULL;
if ((p->prior->data.state == Free) && (p->prior->data.address + p->prior->data.size == p->data.address))
{
p->prior->data.size += p->data.size;
p->prior->next = NULL;
free(p);
}
break;
}
else if ((p->prior->data.state == Free)&&(p->prior->data.address+p->prior->data.size == p->data.address))
{
if ( p->next->data.state == Free && (p->data.address + p->data.size == p->next->data.address))
{
p1 = p->next;
p->data.size += p->next->data.size;
p->next->next->prior = p;
p->next = p->next->next;
free(p1);
}
p->prior->data.size += p->data.size;
p->prior->next = p->next;
p->next->prior = p->prior;
free(p);
break;
}
else if ((p->next->data.state == Free) && (p->data.address + p->data.size == p->next->data.address))
{
p1 = p->next;
p->data.size += p->next->data.size;
p->next = p->next->next;
p->next->prior = p;
free(p1);
break;
}
break;
}
p = p->next;
}
cout << "回收成功!" << endl;
return OK;
}
//--------------- 显示主存分配情况 ------------------
void show()
{
cout << "+++++++++++++++++++++++++++++++++++++++\n";
cout << "+++ 主 存 分 配 情 况 +++\n";
cout << "+++++++++++++++++++++++++++++++++++++++\n";
DuLNode *p = block_first->next;
while (p)
{
cout << "分 区 号:";
if (p->data.ID == Free) cout << "Free" << endl;
else cout << p->data.ID << endl;
cout << "起始地址:" << p->data.address << endl;
cout << "分区大小:" << p->data.size << " KB" << endl;
cout << "状 态:";
if (p->data.state == Free) cout << "空 闲" << endl;
else cout << "已分配" << endl;
cout << "——————————————" << endl;
p = p->next;
}
}
//----------------------- 主 函 数---------------------------
void main()
{
int ch;//算法选择标记
cout << " 动态分区分配方式的模拟 \n";
cout << "************************************\n";
cout << "** 1)首次适应算法 2)最佳适应算法 **\n";
cout << "************************************\n";
cout << "请选择分配算法:";
cin >> ch;
Initblock(); //开创空间表
int choice; //操作选择标记
while (1)
{
cout << "********************************************\n";
cout << "** 1: 分配内存 2: 回收内存 **\n";
cout << "** 3: 查看分配 0: 退 出 **\n";
cout << "********************************************\n";
cout << "请输入您的操作 :";
cin >> choice;
if (choice == 1) alloc(ch); // 分配内存
else if (choice == 2) // 内存回收
{
int ID;
cout << "请输入您要释放的分区号:";
cin >> ID;
free(ID);
}
else if (choice == 3) show();//显示主存
else if (choice == 0) break; //退出
else //输入操作有误
{
cout << "输入有误,请重试!" << endl;
continue;
}
}
}
二:首次适应算法
动态分区分配算法
一、实验内容
编写一个内存动态分区分配模拟程序,模拟内存的分配和回收的完整过程。
二、实验目的
主存的分配和回收的实现与主存储器的管理方式有关的,通过本实验帮助学生理解在可变分区管理方式下应怎样实现主存空间的分配和回收。
三、实验原理
模拟在可变分区管理方式下采用最先适应算法实现主存分配和回收。
(1)可变分区方式是按作业需要的主存空间大小来分割分区的。当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入。随着作业的装入、撤离,主存空间被分成许多个分区,有的分区被作业占用,而有的分区是空闲的。例如:
操作系统 | ||
作业1 | ||
作业3 | ||
空闲区 | ||
作业2 | ||
|
空闲区
|
为了说明哪些区是空闲的,可以用来装入新作业,必须要有一张空闲区说明表,格式如下:
|
起 址 |
长 度 |
状 态 |
第一栏 |
14 K |
12 K |
未 分 配 |
第二栏 |
32 K |
96 K |
未 分 配 |
M |
M |
M |
M |
|
|
|
其中,起址——指出一个空闲区的主存起始地址。
长度——指出从起始地址开始的一个连续空闲的长度。
状态——有两种状态,一种是“未分配”状态,指出对应的由起址指出的某个长度的区域是空闲区。
(2) 当有一个新作业要求装入主存时,必须查空闲区说明表,从中找出一个足够大的空闲区。有时找到的空闲区可能大于作业需要量,这时应把原来的空闲区变成两部分:一部分分给作业占用;另一部分又成为一个较小的空闲区。为了尽量减少由于分割造成的空闲区,而尽量保存高地址部分有较大的连续空闲区域,以利于大型作业的装入。为此,在空闲区说明表中,把每个空闲区按其地址顺序登记,即每个后继的空闲区其起始地址总是比前者大。
(3) 采用最先适应算法(顺序分配算法)分配主存空间。
按照作业的需要量,查空闲区说明表,顺序查看登记栏,找到第一个能满足要求的空闲区。当空闲区大于需要量时,一部分用来装入作业,另一部分仍为空闲区登记在空闲区说明表中。
由于本实验是模拟主存的分配,所以把主存区分配给作业后并不实际启动装入程序装入作业,而用输出“分配情况”来代替。
(4) 当一个作业执行结束撤离时,作业所占的区域应该归还,归还的区域如果与其它空闲区相邻,则应合成一个较大的空闲区,登记在空闲区说明表中。
(5) 请按最先适应算法设计主存分配和回收的程序。假设初始时主存中没有作业,现按下面序列进行内存的申请与释放:
作业1申请300K,作业2申请100K,作业1释放300K,作业3申请150K,
作业4申请30K, 作业5申请40K, 作业6申请60K, 作业4释放30K。
一、动态内存分配的几种分配方式(具体可以点粉色字体链接)
二、用C语言模拟实验首次适应算法
(1)说一下思路吧,我的思路是利用数据结构中的二叉树
①打印分区表的时候,只需遍历一遍二叉树,然后输出度为0的节点(没有孩子的节点)
②作业完成后,释放空间时,通过插入时候给的作业名称来遍历、寻找到该节点,将其状态修改为free即可
注意:
还有就是释放后,空闲区的合并问题。由于本次实验所插入、释放作业后,无需合并,这点在本次实验忽略(虽然题目有要求。。)
(2)代码块
- //动态内存分配
- #include<stdio.h>
- int temp=0;//定义一个全局变量!这个变量起很大作用
- typedef struct _BiTNode//定义 表 的结构体
- {
- int address;//首地址
- int length;//空闲区长度
- bool state;//区域状态 “1”表示已分配, “0”表示未分配
- int homework; //作业名
- struct _BiTNode *lchild;//指向左孩子的指针
- struct _BiTNode *rchild;//右孩子
- }BiTNode,*pBiTree;
- void Init_BiTree(pBiTree l)
- {
- l->address = 5;
- l->length = 507;
- l->state = 0;
- l->homework=NULL;
- l->lchild = NULL;
- l->rchild = NULL;
- printf("初始化完成!\n");
- }
- int Print(pBiTree p)
- {
- printf("\n\t\t%d\t%d\t",p->address,p->length);
- if(p->state==1)
- printf("Busy \t");
- else
- printf("Free \t");
- if(p->homework!=0)
- printf("%d\n",p->homework);
- else
- printf("\n");
- }
- //先序遍历
- void PreOrder(pBiTree p)
- {
- if(p != NULL)
- {
- if(!p->lchild&&!p->rchild)
- Print(p); //输出该结点
- PreOrder(p->lchild); //遍历左子树
- PreOrder(p->rchild); //遍历右子树
- }
- }
- void Insert_PreOrder(pBiTree p,int length,int homework)//插入新作业
- {
- if(p != NULL)
- {
- if((p->state==0)&&(length<p->length)&&(!p->lchild)&&(!p->rchild)&&temp==0)//判断节点是否有左右孩子,是否小于空闲区长度,是否状态为0(表示区域无作业运行)
- {
- pBiTree x1 =new BiTNode;//进行插入,动态申请两个空间 x1,x2
- pBiTree x2 =new BiTNode;
- x1->homework=homework;//x1为作业
- x2->homework=NULL;//x2为剩余的空闲区
- x1->address=p->address;//把原空闲区的首地址给作业的首地址
- x1->state=1;//作业的状态改为1
- x1->length=length;//作业的长度为传入的长度
- x2->address=x1->address+length;//新空闲区的首地址为 x1首地址与x1长度之和
- x2->length=p->length-x1->length;
- p->lchild=x1;
- p->rchild=x2;
- x2->state=0;
- x1->lchild=NULL;
- x1->rchild=NULL;
- x2->rchild=NULL;
- x2->lchild=NULL;
- temp=1;
- }
- else
- {
- Insert_PreOrder(p->lchild,length,homework); //遍历左子树
- Insert_PreOrder(p->rchild,length,homework); //遍历右子树
- }
- }
- }
- void Delect_PreOrder(pBiTree p,int homework) //遍历修改,将状态修改为0。即为空闲区
- {
- if(p != NULL)
- {
- if(p->homework==homework)//当查询到作业名相同的作业。进行修改
- {
- p->homework=NULL;//将作业名修改为空
- p->state=0;//将作业名状态修改为空闲
- }
- Delect_PreOrder(p->lchild,homework); //遍历左子树
- Delect_PreOrder(p->rchild,homework); //遍历右子树
- }
- }
- int main()
- {
- BiTNode l;
- Init_BiTree(&l);
- //初始化
- printf("\n 初始化:\t首地址\t长度\t状态\t作业名\n");
- PreOrder(&l);
- //插入作业1
- temp=0;
- Insert_PreOrder(&l,300,1);
- printf("\n插入作业1:\t首地址\t长度\t状态\t作业名\n");
- PreOrder(&l);
- //插入作业2
- temp=0;
- Insert_PreOrder(&l,100,2);
- printf("\n插入作业2:\t首地址\t长度\t状态\t作业名\n");
- PreOrder(&l);
- //释放作业1
- Delect_PreOrder(&l,1);
- printf("\n释放作业1:\t首地址\t长度\t状态\t作业名\n");
- PreOrder(&l);
- //插入作业3
- temp=0;
- Insert_PreOrder(&l,150,3);
- printf("\n插入作业3:\t首地址\t长度\t状态\t作业名\n");
- PreOrder(&l);
- //插入作业4
- temp=0;
- Insert_PreOrder(&l,30,4);
- printf("\n插入作业4:\t首地址\t长度\t状态\t作业名\n");
- PreOrder(&l);
- //插入作业5
- temp=0;
- Insert_PreOrder(&l,40,5);
- printf("\n插入作业5:\t首地址\t长度\t状态\t作业名\n");
- PreOrder(&l);
- //插入作业6
- temp=0;
- Insert_PreOrder(&l,60,6);
- printf("\n插入作业6:\t首地址\t长度\t状态\t作业名\n");
- PreOrder(&l);
- //释放作业4
- Delect_PreOrder(&l,4);
- printf("\n释放作业4:\t首地址\t长度\t状态\t作业名\n");
- PreOrder(&l);
- return 0;
- }
(3)执行结果
三:最佳适应算法和首次适应算法
首次适应算法:
找到第一个满足程序的内存块,并将其分配给程序
最佳适应算法:
找到所有的满足程序的内存块,并将其中最小的内存块分配给程序
- #include <iostream>
- #include <string.h>
- #include <stdio.h>
- using namespace std;
- struct node{
- int st,size,num;
- bool work;
- node *next,*pre;
- node(){
- work = false;
- st = 0;
- next = NULL;
- pre = NULL;
- }
- }*add,*mem;
- int work_num,oper,Size;
- void show(){
- printf("------------------------------------------------------------------------\n\n");
- printf("\t\t当前的内存分配情况如下:\n\n");
- node *now = mem;
- printf("\t起始地址\t空间大小\t工作状态\t作业号\t\n\n");
- while(true){
- printf("\t%d\t\t%d kb\t\t%s\t\t",now->st,now->size,now->work?"Busy":"Free");
- if(now->work) printf("%d\t",now->num);
- printf("\n\n");
- if(now->next==NULL){
- break;
- }
- now = now->next;
- }
- printf("------------------------------------------------------------------------\n\n");
- }
- bool find1(){
- //找最小的
- node *now = mem;
- node *get = NULL;
- while(true){
- if(!now->work){
- if(now->size>=Size){
- //找出所有的可放置内存块中内存最小的
- if(get==NULL){
- get = now;
- }else{
- if(get->size > now->size){
- get = now;
- }
- }
- }
- }
- if(now->next==NULL) break;
- now = now->next;
- }
- // 若找不到放置位置 返回不可放置
- if(get==NULL) return false;
- // 更新内存情况
- get->work = true;
- get->num = work_num;
- if(get->size>Size){
- add = new node();
- add->size = get->size - Size;
- get->size = Size;
- add->st = get->st + get->size;
- add->next = get->next;
- get->next = add;
- add->pre = get;
- }
- return true;
- }
- bool find2(){
- //找最前面的
- node *now = mem;
- while(true){
- if(!now->work){
- if(now->size>=Size){
- //找到第一个可放置的内存空间 更新内存状况 返回分配结果
- now->work = true;
- now->num = work_num;
- if(now->size>Size){
- add = new node();
- add->size = now->size - Size;
- now->size = Size;
- add->st = now->st + now->size;
- add->next = now->next;
- now->next = add;
- add->pre = now;
- }
- return true;
- }
- }
- if(now->next==NULL) break;
- now = now->next;
- }
- return false;
- }
- bool find(int ope){
- // 分配内存操作
- if(ope){
- //最佳适应算法
- return find1();
- }else{
- //首次适应算法
- return find2();
- }
- }
- bool reget(){
- // 回收内存操作
- node *now = mem;
- while(true){
- if(now->num==work_num&&now->work){
- //找到对应工作号且在工作的内存区
- node *pre = now,*next = now->next;
- int pre_unused_memSize = 0,next_unused_memSize = 0;
- //将空闲的内存区合并
- while(pre->pre!=NULL&&!pre->pre->work){
- pre_unused_memSize += pre->size;
- pre = pre->pre;
- }
- while(next!=NULL&&!next->work){
- next_unused_memSize += next->size;
- next = next->next;
- }
- now = pre;
- now->next = next;
- now->size += pre_unused_memSize + next_unused_memSize;
- now->work = false;
- if(next!=NULL) next->pre = now;
- return true;
- }
- if(now->next==NULL){
- break;
- }
- now = now->next;
- }
- return false;
- }
- void work(int ope){
- // 执行操作
- while(true){
- printf("\n\t1: 分配内存 2: 回收内存 0: 退出\n\n请输入操作:");
- scanf("%d",&oper);
- printf("\n");
- if(oper==1){
- // 分配内存
- printf("请输入作业号: ");
- scanf("%d",&work_num);
- printf("\n");
- printf("请输入需要分配的内存大小(kb): ");
- scanf("%d",&Size);
- printf("\n");
- if(find(ope)){
- printf("内存分配成功!\n\n");
- }else{
- printf("内存分配失败!\n\n");
- }
- show();
- }else if(oper==2){
- // 回收内存
- printf("请输入作业号: ");
- scanf("%d",&work_num);
- printf("\n");
- if(reget()){
- printf("\t\t内存回收成功!\n\n");
- }else{
- printf("\t\t内存回收失败!\n\n");
- }
- show();
- }else{
- // 操作结束
- break;
- }
- }
- }
- void delete_mem(node *now){
- // 清空内存
- if(now->next!=NULL) delete_mem(now->next);
- delete now;
- }
- int main()
- {
- int ope;
- while(true){
- printf("\t\t请选择需要模拟的分配算法\n\n\t\t0\t首次适应算法\n\n\t\t1\t最佳适应算法\n\n");
- printf("\t\t你的选择是 : ");
- scanf("%d",&ope);
- printf("\n");
- mem = new node(); mem->size = 1000;
- if(ope){
- //最佳适应算法 找到最小可存储空间
- work(ope);
- printf("\t\t最佳适应算法模拟结束\n\n\n");
- printf("-----------------------------------------------------------------------\n\n");
- }else{
- //首次适应算法 找到第一个可存储空间
- work(ope);
- printf("\t\t首次适应算法模拟结束\n\n\n");
- printf("-----------------------------------------------------------------------\n\n");
- }
- delete_mem(mem);
- }
- return 0;
- }
四:首次适应算法和最佳适应算法
- #include <stdio.h>
- #define getpch(type) (type*)mallloc(sizeof(type))
- strct LNode
- {
- int size;
- int start;
- int end;
- struct LNode *next;
- struct LNode *front;
- }*L;
- typedeft struct LNode LN;
- LN *find;
- int n;
- void InsertList(int size,int start)
- {
- LN *p,*s,*t;
- p=L;
- printf("\n空闲区号 长度 起始位置 终止位置\n");
- for(i=1;i<=n;i++)
- {
- printf("%3d\t %3d\t%3d\t %4d\n",i,p->size,p->start,p->end);
- p=p->next;
- }
- }
- void BFSortList()
- {
- LN *p,*s,*t;
- int min_size,i;
- int size,start,end;
- t=L->next;
- p=L->next;
- for(i=0;i<n;i++)
- {
- s=p->next;
- min_size=p->size;
- while(s)
- {
- if(min_size>s->size)
- {
- min_size=s->size;
- t=s;
- }
- s=s->next;
- }
- size=t->size;
- start=t->start;
- end=t->end;
- t->size=p->size;
- t->start=p->start;
- t->end=p->end;
- p->size=size;
- p->start=start;
- p->end=end;
- t=->next;
- p=p->next;
- }
- }
- void SortList()
- {
- LN *p.*s,*t;
- int min_start,i;
- int size,start,end;
- t=L->next;
- p=L->next;
- for(i=0;i<n;i++)
- {
- s=p->next;
- min_start=p->start;
- while(s)
- {
- if(min_start>s->start)
- {
- min_start=s->start;
- t=s;
- }
- s=s->next;
- }
- size=t->size;
- start=t->start;
- end=t->end;
- t->size=p->size;
- t->start=p->start;
- t->end=p->end;
- p->size=size;
- p->start=start;
- p->end=end;
- t=->next;
- p=p->next;
- }
- }
- void GetFree()
- {
- int size,start,i;
- L=getpch(LN);
- L->next=NULL;
- L->front=NULL;
- printf("请输入空闲区数:");
- scanf("%d",&n);
- for(i=1;i<=n;i++)
- {
- printf("请输入第%2d空闲区的大小和初始地址。\n",i);
- scanf("%3d,%3d",&size,&start);
- InsertList(size,start);
- }
- printf("\n按任意键继续。");
- }
- void Assign(int size)
- {
- LN *p,*t;
- p=L->next;
- t=L;
- while(p)
- {
- p=p->next;
- t=t->next;
- if(!p)
- {
- printf("没有足够大的空间。\n");
- }
- else
- {
- p->size=p->size-size;
- p->start=p->start+size;
- if(p->size==0)
- {
- t->next=p->next;
- p->next->front=t;
- n--;
- free(p);
- }
- }
- printf("分配成功!\n");
- printf("分配后的空闲链表情况如下:\n");
- PrintList();
- break;
- }
- }
- int flag=-1;
- void NF_Assign(int size)
- {
- LN *P,*t;
- int i=n;
- p=find->next;
- t=find;
- while(p)
- {
- if(size>p->size)
- {
- p=p->next;
- t=t->next;
- if(!p)
- {
- printf("没有足够大的空间去分配!分配不成功。");
- }
- }
- else
- {
- p->size=p->size-size;
- p->start=p->start+size;
- find=p;
- if(p->size==0)
- {
- t->next=p->next;
- p->next-front=t;
- n--;
- free(p);
- }
- printf("分配成功!\n");
- flag=1;
- printf("分配后的空闲链表情况如下:\n");
- Print(L);
- break;
- }
- }
- if(flag==-1)
- {
- p=L->next;
- t=L;
- while(p!=find)
- {
- if(size>p->size)
- {
- p=p->size;
- t=t->next;
- if(!p)
- {
- printf("没有足够大的空间去分配!分配不成功。");
- }
- }
- else
- {
- p->size=p->size-size;
- p->start=p->start+size;
- find=t;
- if(p->size==0)
- {
- t->next=p->next;
- p->next-front=t;
- n--;
- free(p);
- }
- printf("分配成功!\n");
- printf("分配后的空闲链表情况如下:\n");
- PrintList(L);
- break;
- }
- }
- }
- }
- void Recover(int start,int end)
- {
- LN *p,*t;
- int size,flag=0;
- size=end-start;
- p=L->next;
- t=p->next;
- while(p)
- {
- if(t&&p->end==start&&t->start==end)
- {
- p->size=p->size+size+t->size;
- p->end=t->end;
- p->next=t->next;
- t->next->front=p;
- free(t);
- n--;
- SortList(L);
- flag=1;
- break;
- }
- else if(p->end==start)
- {
- flag=1;
- p->size=p->size+size;
- p->end=p->end+size;
- SortList(L);
- break;
- }
- else if(p->start==end)
- {
- p->size=p->size+size;
- p->start=start;
- SortList(L);
- flag=1;
- break;
- }
- p=p->next;
- if(p)
- t=p->next;
- }
- if(flag==0)
- {
- InsertList(size,start);
- n++;
- }
- printf("回收后的空闲链表情况如下:");
- PrintList();
- printf("\n按任意间继续。");
- }
- void main()
- {
- int start,end,size;
- int m;
- GetFree();
- getch();
- system("cls");
- printf("请选择服务类型:\n");
- printf("\t1:首次适应算法\n");
- printf("\t3:最佳适应算法\n");
- printf("\t4:最佳适应算法\n");
- printf("\t0:退出\n");
- printf("\t输入您要的选项:\n");
- scanf("%d",&m);
- if(m==2)find=L;
- while(m)
- {
- switch(m)
- {
- case 1:
- SortList();
- printf("\n空闲链表情况:\n");
- PrintList();
- printf("请输入进程需要的空闲区大小:");
- scanf("%d",&size);
- Assign(size);
- printf("\n按任意键继续");
- break;
- case 2:
- SortList();
- printf("\n空闲链表情况:\n");
- PrintList();
- printf("请输入进程需要的空闲区大小:");
- scanf("%d",&size);
- NF_Assign(size);
- printf("\n按任意键继续");
- break;
- case 3:
- BFSortList();
- printf("\n空闲链表情况:\n");
- PrintList();
- printf("请输入进程需要的空闲区大小:");
- scanf("%d",&size);
- Assign(size);
- printf("\n按任意键继续");
- break;
- case 4:
- printf("请输入回收去的首地址和中止地址:");
- scanf("%3d,%3d",&start,&end);
- Recover(start,end);
- break;
- case 0: exit(0);
- default:printf("\n\t\t输入错误,请重新输入");getch();
- }
- getch();
- system("cls");
- printf("请选择服务类型:\n");
- printf("\t1:首次适应算法\n");
- printf("\t3:最佳适应算法\n");
- printf("\t4:最佳适应算法\n");
- printf("\t0:退出\n");
- printf("\t输入您要的选项:\n");
- scanf("%d",&m);
- }
- }
五:合集三个算法
- /*所有的链表带有头节点,以便于排序*/
- #include<stdio.h>
- #include<stdlib.h>
- #include<malloc.h>
- #define PROCESS_NAME_LEN 32 /*进程名长度*/
- #define MIN_SLICE 10 /*最小碎片的大小*/
- #define DEFAULT_MEM_SIZE 1024 /*内存大小*/
- #define DEFAULT_MEM_START 0 /*起始位置*/
- /* 内存分配算法 */
- #define MA_FF 1
- #define MA_BF 2
- #define MA_WF 3
- int mem_size = DEFAULT_MEM_SIZE; /*内存大小*/
- int ma_algorithm = MA_FF; /*当前分配算法*/
- static int pid = 0; /*初始pid*/
- int flag = 0; /*设置内存大小标志*/
- /*描述每一个空闲块的数据结构*/
- struct free_block_type {
- int size;
- int start_addr;
- struct free_block_type *next;
- };
- /*指向内存中空闲块链表的首指针*/
- struct free_block_type *free_block;
- /*每个进程分配到的内存块的描述*/
- struct allocated_block {
- int pid;
- int size;
- int start_addr;
- char process_name[PROCESS_NAME_LEN];
- struct allocated_block *next;
- };
- /*进程分配内存块链表的首指针*/
- struct allocated_block *allocated_block_head = NULL;
- //函数声明
- void display_menu();
- int set_mem_size();
- void set_algorithm();
- void rearrange(int algorithm);
- int new_process();
- int allocate_mem(struct allocated_block *ab);
- void kill_process();
- int free_mem(struct allocated_block *ab);
- int dispose(struct allocated_block *free_ab);
- int display_mem_usage();
- //allocated_block* find_process(int pid);
- void rearrange_FF();
- void rearrange_BF();
- void rearrange_WF();
- /*按FF算法重新整理内存空闲块链表*/
- void rearrange_FF()
- {
- //请自行补充 m代表头,p。q分别代表交换的两个节点 n代表交换截至位置
- struct free_block_type *p, *q, *m, *n;
- if ( free_block->next->next != NULL)
- {
- n = NULL;
- while (n != free_block->next->next)
- {
- m = free_block;
- p = free_block->next;
- q = p->next;
- while (q != n)
- {
- if (p->start_addr > q->start_addr)
- {
- p->next = q->next;
- q->next = p;
- m->next = q;
- }
- m = m->next;
- p = m->next;
- q = p->next;
- }
- n = p;
- }
- }
- }
- /*按BF算法重新整理内存空闲块链表*/
- void rearrange_BF()
- {
- //请自行补充
- //请自行补充 m代表头,p。q分别代表交换的两个节点 n代表交换截至位置
- struct free_block_type *p, *q, *m, *n;
- if (free_block->next->next != NULL)
- {
- n = NULL;
- while (n != free_block->next->next)
- {
- m = free_block;
- p = free_block->next;
- q = p->next;
- while (q != n)
- {
- if (p->size > q->size)
- {
- p->next = q->next;
- q->next = p;
- m->next = q;
- }
- m = m->next;
- p = m->next;
- q = p->next;
- }
- n = p;
- }
- }
- }
- /*按WF算法重新整理内存空闲块链表*/
- void rearrange_WF()
- {
- //请自行补充
- //请自行补充 m代表头,p。q分别代表交换的两个节点 n代表交换截至位置
- struct free_block_type *p, *q, *m, *n;
- if (free_block->next->next != NULL)
- {
- n = NULL;
- while (n != free_block->next->next)
- {
- m = free_block;
- p = free_block->next;
- q = p->next;
- while (q != n)
- {
- if (p->size < q->size)
- {
- p->next = q->next;
- q->next = p;
- m->next = q;
- }
- m = m->next;
- p = m->next;
- q = p->next;
- }
- n = p;
- }
- }
- }
- //查找进程
- struct allocated_block* find_process(int pid)
- {
- struct allocated_block *abb;
- for (abb = allocated_block_head->next; abb && abb->pid != pid; abb = abb->next);
- return abb;
- }
- //释放内存
- int free_mem(struct allocated_block *ab)
- {
- struct free_block_type * p;
- //分配空闲分区表的中的一个节点 每一次选择头节点后后面插入,并且完成之后查看当前算法,重新整理链表
- p = (struct free_block_type *)malloc(sizeof(struct free_block_type));
- p->next = free_block->next;
- free_block->next = p;
- p->size = ab->size;
- p->start_addr = ab->start_addr;
- return 1;
- }
- //释放要杀死进程的节点
- int dispose(struct allocated_block *ab)
- {
- struct allocated_block *p;
- for (p = allocated_block_head; p && p->next != ab; p = p->next);
- p->next = ab->next;
- free(ab);
- return 1;
- }
- //杀死进程
- void kill_process()
- {
- struct allocated_block *ab;
- int pid;
- printf("Kill Process, pid=");
- scanf("%d", &pid);
- getchar();
- ab = find_process(pid);
- if (ab != NULL)
- {
- free_mem(ab);
- dispose(ab);
- }
- }
- int allocate_mem(struct allocated_block *ab)
- {
- struct free_block_type *p, *q, *temp;
- int sum = 0;
- if (free_block->next == NULL)
- {
- printf("no memory");
- return;
- }
- //当前算法进行整理内存
- rearrange(ma_algorithm);
- //根据当前算法在空闲分区链表中搜索合适空闲分区进行分配,分配时注意以下情况:
- // 1. 找到可满足空闲分区且分配后剩余空间足够大,则分割
- // 2. 找到可满足空闲分区且但分配后剩余空间(最小碎片化)比较小,则一起分配
- // 3. 找不可满足需要的空闲分区但空闲分区之和能满足需要,则采用内存紧缩技术,进行空闲分区的合并,然后再分配
- // 4. 在成功分配内存后,应保持空闲分区按照相应算法有序
- // 5. 分配成功则返回1,否则返回-1
- //如果首次适应 和最佳适应差不多 从链首开始查找,如果找到,则开始分配,如果没有找到,采用分区紧缩技术,如果可以分配,则分配,不能分配,返回-1
- if (ma_algorithm == MA_FF || ma_algorithm == MA_BF)
- {
- //开始寻找符合条件的节点
- for (p = free_block, q = p->next; q && q->size < ab->size; p = p->next, q = p->next);
- //找到
- if (q)
- {
- //判断是否达到最小碎片程度
- if ((q->size - ab->size) <= MIN_SLICE)
- {
- //全部分配
- ab->start_addr = q->start_addr;
- ab->size = q->size;
- //释放q节点
- p->next = q->next;
- free(q);
- }
- else
- {
- ab->start_addr = q->start_addr;
- q->start_addr = q->start_addr + ab->size;
- q->size = q->size - ab->size;
- }
- }
- //开始内存紧缩
- else
- {
- for (q = free_block->next; q; q = q->next)
- {
- sum += q->size;
- if (sum >= ab->size)
- {
- break;
- }
- }
- if (q)
- {
- //第一个空闲分区大小更改为sum,并且除了第一个,其他结点全部删除
- free_block->next->size = sum;
- p = free_block->next;
- for (temp = p->next; temp != q; temp = p->next)
- {
- p->next = temp->next;
- free(temp);
- }
- p->next = q->next;
- free(q);
- p->start_addr = p->start_addr + ab->size;
- p->size = p->size - ab->size;
- //如果剩余空间为0 则直接释放当前的空间
- }
- else
- {
- return -1;
- }
- }
- }
- //最差适应
- else if (ma_algorithm == MA_WF)
- {
- //只需要找到第一个最大的空闲分区 如果满足,则分配,不满足则判断能否进行合并,如果可以,分配
- if (free_block->next->size >= ab->size)
- {
- if (free_block->next->size - ab->size >= 10)
- {
- ab->start_addr = free_block->next->start_addr;
- free_block->next->start_addr += ab->size;
- free_block->next->size -= ab->size;
- }
- else
- {
- p = free_block->next;
- free_block->next = p->next;
- free(p);
- }
- }
- else
- {
- for (q = free_block->next; q; q = q->next)
- {
- sum += q->size;
- if (sum >= ab->size)
- {
- break;
- }
- }
- if (q)
- {
- //第一个空闲分区大小更改为sum,并且除了第一个,其他结点全部删除
- free_block->next->size = sum;
- p = free_block->next;
- for (temp = p->next; temp != q; temp = p->next)
- {
- p->next = temp->next;
- free(temp);
- }
- p->next = q->next;
- free(q);
- ab->start_addr = free_block->next->start_addr;
- p->start_addr = p->start_addr + ab->size;
- p->size = p->size - ab->size;
- //如果剩余空间为0 则直接释放当前的空间
- }
- else
- {
- return -1;
- }
- }
- }
- return 1;
- }
- //创建一个新的进程
- int new_process()
- {
- struct allocated_block *ab;
- int size;
- int ret;
- ab = (struct allocated_block *)malloc(sizeof(struct allocated_block));
- if (!ab) exit(-5);
- ab->next = NULL;
- pid++;
- sprintf(ab->process_name, "PROCESS-%02d", pid);
- ab->pid = pid;
- printf("Memory for %s:", ab->process_name);
- scanf("%d", &size);
- getchar();
- if (size > 0) ab->size = size;
- ret = allocate_mem(ab); /* 从空闲区分配内存,ret==1表示分配ok*/
- /*如果此时allocated_block_head尚未赋值,则赋值*/
- if ((ret == 1) && (allocated_block_head->next == NULL))
- {
- allocated_block_head->next = ab;
- return 1;
- }
- /*分配成功,将该已分配块的描述插入已分配链表*/
- else if (ret == 1)
- {
- ab->next = allocated_block_head->next;
- allocated_block_head->next = ab;
- return 2;
- }
- else if (ret == -1)
- {
- /*分配不成功*/
- printf("Allocation fail\n");
- free(ab);
- return -1;
- }
- return 3;
- }
- int set_mem_size()
- {
- int size;
- if (flag != 0)
- { //防止重复设置
- printf("Cannot set memory size again\n");
- return 0;
- }
- printf("Total memory size =");
- scanf("%d", &size);
- getchar();
- if (size > 0)
- {
- mem_size = size;
- free_block->next->size = mem_size;
- }
- flag = 1;
- return 1;
- }
- void rearrange(int algorithm)
- {
- switch (algorithm)
- {
- case MA_FF: rearrange_FF(); break;
- case MA_BF: rearrange_BF(); break;
- case MA_WF: rearrange_WF(); break;
- }
- }
- /* 设置当前的分配算法 */
- void set_algorithm()
- {
- int algorithm;
- printf("----------------------------------\n");
- printf("\t1 - First Fit\n");
- printf("\t2 - Best Fit \n");
- printf("\t3 - Worst Fit \n");
- scanf("%d", &algorithm);
- getchar();
- if (algorithm >= 1 && algorithm <= 3)
- ma_algorithm = algorithm;
- //按指定算法重新排列空闲区链表
- rearrange(ma_algorithm);
- }
- //释放所有链表
- void do_exit()
- {
- struct free_block_type *p;
- struct allocated_block *q;
- p = free_block->next;
- q = allocated_block_head->next;
- while (free_block->next != NULL)
- {
- free_block->next = p->next;
- free(p);
- p = free_block->next;
- }
- free(free_block);
- while (allocated_block_head->next)
- {
- allocated_block_head->next = q->next;
- free(q);
- q = allocated_block_head->next;
- }
- free(allocated_block_head);
- }
- /*初始化空闲块,默认为一块,可以指定大小及起始地址*/
- struct free_block_type* init_free_block(int mem_size) {
- struct free_block_type *fb, *p;
- struct allocated_block * q;
- fb = (struct free_block_type *)malloc(sizeof(struct free_block_type));
- p = (struct free_block_type *)malloc(sizeof(struct free_block_type));
- q = (struct allocated_block*)malloc(sizeof(struct allocated_block));
- if (fb == NULL || p == NULL || q == NULL)
- {
- printf("No mem\n");
- return NULL;
- }
- q->next = NULL;
- allocated_block_head = q;
- p->size = mem_size;
- p->start_addr = DEFAULT_MEM_START;
- p->next = NULL;
- fb->next = p;
- return fb;
- }
- int display_mem_usage()
- {
- struct free_block_type *fbt = free_block->next;
- struct allocated_block *ab = allocated_block_head->next;
- if (fbt == NULL) return(-1);
- printf("----------------------------------------------------------\n");
- /* 显示空闲区 */
- printf("Free Memory:\n");
- printf("%20s %20s\n", " start_addr", " size");
- while (fbt != NULL)
- {
- printf("%20d %20d\n", fbt->start_addr, fbt->size);
- fbt = fbt->next;
- }
- /* 显示已分配区 */
- printf("\nUsed Memory:\n");
- printf("%10s %20s %10s %10s\n", "PID", "ProcessName", "start_addr", " size");
- while (ab != NULL)
- {
- printf("%10d %20s %10d %10d\n", ab->pid, ab->process_name, ab->start_addr, ab->size);
- ab = ab->next;
- }
- printf("----------------------------------------------------------\n");
- return 0;
- }
- /*显示菜单*/
- void display_menu()
- {
- printf("\n");
- printf("1 - Set memory size (default=%d)\n", DEFAULT_MEM_SIZE);
- printf("2 - Select memory allocation algorithm\n");
- printf("3 - New process \n");
- printf("4 - Terminate a process \n");
- printf("5 - Display memory usage \n");
- printf("0 - Exit\n");
- }
- int main(void)
- {
- char choice; pid = 0;
- free_block = init_free_block(mem_size); //初始化空闲区
- while (1)
- {
- display_menu(); //显示菜单
- fflush(stdin);
- choice = getchar();
- fflush(stdin);
- //获取用户输入
- switch (choice)
- {
- case '1': set_mem_size(); break; //设置内存大小
- case '2': set_algorithm(); flag = 1; break;//设置算法
- case '3': new_process(); flag = 1; break;//创建新进程
- case '4': kill_process(); flag = 1; break;//删除进程
- case '5': display_mem_usage(); flag = 1; break; //显示内存使用
- case '0': do_exit(); exit(0); //释放链表并退出
- default: break;
- }
- }
- return 0;
- }