实验指南
1.本实验是模拟存储管理方式中的可变分区分配与回收算法,系统需要建立两张分区表,分别是未(已)分配分区表,然后根据待装入作业的名称和大小到未分配分区列表中查找(具体包含最先/最优/最坏适配算法)满足要求的空闲分区,再将该分区一分为二,前半部分分配给作业使用并登记到已分配分区表的空栏中,剩余部分仍修改为新的空闲分区,最后通过动态重定位方式完成地址转换;当作业运行结束时,根据该作业名查找已分配分区表,找到与作业名相同的分区,然后将该分配从已分配分区表中删除,最后按照无上邻无下邻、有上邻无下邻、无上邻有下邻和有上邻有下邻四种形式分别修改未分配分区表。
测试用例:
样例一:
最先分配算法
256
40
1
1
JOB_A
15
1
1
JOB_B
50
1
1
JOB_C
10
1
1
JOB_D
25
1
1
JOB_E
14
2
JOB_B
2
JOB_D
1
1
JOB_F
32
2
JOB_C
2
JOB_E
2
JOB_A
2
JOB_F
样例二:
最优分配算法
256
40
1
2
JOB_A
15
1
2
JOB_B
50
1
2
JOB_C
10
1
2
JOB_D
5
1
2
JOB_E
14
2
JOB_D
1
2
JOB_H
6
关键代码
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<malloc.h>
#include<string.h>
using namespace std;
//内存结构体
typedef struct memory_node
{
int size; //内存大小
int address; //内存始址
} memoryNode;
memoryNode memory;
//分区结构体
typedef struct link_node
{
int size;//分区大小
int address; //分区始址
char flag[20]; //分区状态,空闲或者占用作业名
struct link_node *next;
} node;
//作业结构体
typedef struct job_node
{
int id;//作业编号
char name[20];//作业名
int size;//作业大小
} job;
void print(node *yfp,node *wfp)
{
printf("\n*******************主存分配情况**************");
printf("\n已分配:");
int count = 1;
node *dy;
dy=yfp->next;
printf("\n分区号 大小(KB) 起始(KB) 状态");
while(dy!=NULL)
{
printf("\n%d\t %d\t\t %d\t ",count,dy->size,dy->address);
if(dy->flag[0] == '\0')
printf("空闲");
else
printf("%s",dy->flag);
dy = dy->next;
count++;
}
printf("\n未分配:");
dy=wfp->next;
printf("\n分区号 大小(KB) 起始(KB) 状态");
while(dy!=NULL)
{
printf("\n%d\t %d\t\t%d\t ",count,dy->size,dy->address);
if(dy->flag[0] == '\0')
printf("空闲");
else
printf("%s",dy->flag);
dy = dy->next;
count++;
}
}
void govern(node *yfp,node *wfp)
{
int option;
printf("\n*****************分配算法*****************");
printf("\n * 1.最先分配算法 *");
printf("\n * 2.最优分配算法 *");
printf("\n * 3.最坏分配算法 *");
printf("\n 请输入选项:");
scanf("%d",&option);
if(option == 1)//最先分配算法
{
job JOB;
printf("\n请输入作业名:");
scanf("%s",&JOB.name);
printf("\n%s需要分配的主存大小(单位:KB):",JOB.name);
scanf("%d",&JOB.size);
node*p = wfp->next;
while(p != NULL)
{
if(p->size >= JOB.size)
{
break;
}
p = p->next;
}
node*NODE = (node*)malloc(sizeof(node));//创建节点插入已分配表中
NODE->next = NULL;
NODE->size = JOB.size;
NODE->address = p->address;
int i=0;
for(i=0;i<strlen(JOB.name);i++)
{
NODE->flag[i] = JOB.name[i];
}
NODE->flag[i+1]='\0';
node*h = yfp;//修改已分配表
while(h->next != NULL)
{
h = h->next;
}
h->next = NODE;
node*hh = wfp->next;
node*pre = wfp;
while(hh != p)
{
pre=hh;
hh = hh->next;
}
if(p->size == JOB.size)
{
pre->next = p->next;
}
else
{
p->address = p->address + JOB.size;
p->size = p->size -JOB.size;
}
printf("\n分配成功!");
print(yfp,wfp);
}
else if(option == 2)//最优分配算法
{
job JOB;
printf("\n请输入作业名:");
scanf("%s",&JOB.name);
printf("\n%s需要分配的主存大小(单位:KB):",JOB.name);
scanf("%d",&JOB.size);
node*p = wfp->next,*best = NULL;
while(p != NULL)
{
if(p->size >= JOB.size && best == NULL)
{
best = p;
}
if(p->size >= JOB.size && p->size <best->size)
{
best = p;
}
p = p->next;
}
node*NODE = (node*)malloc(sizeof(node));//创建节点插入已分配表中
NODE->next = NULL;
NODE->size = JOB.size;
NODE->address = best->address;
int i=0;
for(i=0;i<strlen(JOB.name);i++)
{
NODE->flag[i] = JOB.name[i];
}
NODE->flag[i+1]='\0';
node*h = yfp;//修改已分配表
while(h->next != NULL)
{
h = h->next;
}
h->next = NODE;
node*hh = wfp->next;
node*pre = wfp;
while(hh != best)//修改未分配表
{
pre=hh;
hh = hh->next;
}
if(best->size == JOB.size)
{
pre->next = best->next;
}
else
{
best->address = best->address + JOB.size;
best->size = best->size -JOB.size;
}
printf("\n分配成功!");
print(yfp,wfp);
}
else//最坏分配算法
{
job JOB;
printf("\n请输入作业名:");
scanf("%s",&JOB.name);
printf("\n%s需要分配的主存大小(单位:KB):",JOB.name);
scanf("%d",&JOB.size);
node*p = wfp->next,*best = NULL;
while(p != NULL)
{
if(p->size >= JOB.size && best == NULL)
{
best = p;
}
if(p->size >= JOB.size && p->size >best->size)
{
best = p;
}
p = p->next;
}
node*NODE = (node*)malloc(sizeof(node));//创建节点插入已分配表中
NODE->next = NULL;
NODE->size = JOB.size;
NODE->address = best->address;
int i=0;
for(i=0;i<strlen(JOB.name);i++)
{
NODE->flag[i] = JOB.name[i];
}
NODE->flag[i+1]='\0';
node*h = yfp;//修改已分配表
while(h->next != NULL)
{
h = h->next;
}
h->next = NODE;
node*hh = wfp->next;
node*pre = wfp;
while(hh != best)//修改未分配表
{
pre=hh;
hh = hh->next;
}
if(best->size == JOB.size)
{
pre->next = best->next;
}
else
{
best->address = best->address + JOB.size;
best->size = best->size -JOB.size;
}
printf("\n分配成功!");
print(yfp,wfp);
}
}
void release(node *yfp, node *wfp)
{
print(yfp,wfp);
printf("\n请输入要回收的作业名:");
char NAME[20];
scanf("%s",&NAME);
node *h,*hpre;
hpre = yfp;
h = yfp->next;
while(h!=NULL)
{
string str1,str2;
str1 = h->flag;
str2 = NAME;
const char* p = str1.data();
const char* p2 = str2.data();
if(strcmp(p,p2)==0)
{
break;
}
hpre = h;
h = h->next;
}
node *seek,*pre;
seek = wfp->next;
pre = wfp;
while(seek!=NULL)
{
if(pre == wfp)
{
//printf("//更新未分配表的头部\n");
if(h->address+h->size<=seek->address)
{
if(h->address+h->size<seek->address)
{
hpre->next = h->next;
h->next = seek;
pre->next = h;
h->flag[0] = '\0';
break;
}
else
{
hpre->next = h->next;
seek->address = h->address;
seek->size = seek->size+h->size;
break;
}
}
}
else if(seek->next == NULL)
{
//printf("//更新未分配表的尾部\n");
if(h->address >= seek->address +seek->size)
{
if(h->address > seek->address +seek->size)
{
hpre->next = h->next;
h->next = NULL;
seek->next = h;
h->flag[0] = '\0';
break;
}
else
{
hpre->next = h->next;
seek->size = seek->size+h->size;
break;
}
}
else
{
//printf("//更新未分配表的中部\n");
if(pre->address+pre->size == h->address&&pre->address+pre->size+h->size<seek->address)
{
//printf("//有上邻空闲\n");
pre->size = pre->size+h->size;
hpre->next = h->next;
break;
}
else if(pre->address+pre->size < h->address&&h->address + h->size == seek->address)
{
//printf("//有下邻空闲\n");
seek->address = h->address;
seek->size = seek->size+h->size;
hpre->next = h->next;
break;
}
else if(pre->address+pre->size == h->address&&h->address + h->size == seek->address)
{
//printf("//有上、下邻空闲\n");
pre->size = pre->size + h->size +seek->size;
pre->next = seek->next;
hpre->next = h->next;
break;
}
else if(pre->address+pre->size < h->address&&h->address + h->size < seek->address)
{
//printf("//没有空闲\n");
hpre->next = h->next;
h->next = seek;
pre->next = h;
h->flag[0]='\0';
break;
}
}
}
else
{
//printf("//更新未分配表的中部\n");
if(pre->address+pre->size == h->address&&pre->address+pre->size+h->size<seek->address)
{
//printf("//有上邻空闲\n");
pre->size = pre->size+h->size;
hpre->next = h->next;
break;
}
else if(pre->address+pre->size < h->address&&h->address + h->size == seek->address)
{
//printf("//有下邻空闲\n");
seek->address = h->address;
seek->size = seek->size+h->size;
hpre->next = h->next;
break;
}
else if(pre->address+pre->size == h->address&&h->address + h->size == seek->address)
{
//printf("//有上、下邻空闲\n");
pre->size = pre->size + h->size +seek->size;
pre->next = seek->next;
hpre->next = h->next;
break;
}
else if(pre->address+pre->size < h->address&&h->address + h->size < seek->address)
{
//printf("//没有空闲\n");
hpre->next = h->next;
h->next = seek;
pre->next = h;
h->flag[0]='\0';
break;
}
}
pre = seek;
seek = seek->next;
}
printf("\n回收成功!");
print(yfp,wfp);
}
int main()
{
int option=1;
printf("请输入内存大小为:");
scanf("%d",&memory.size);
printf("\n请输入起始地址大小为:");
scanf("%d",&memory.address);
node*yfp = (node *)malloc(sizeof(node));
yfp->next =NULL;
node*wfp = (node *)malloc(sizeof(node));
node*p = (node *)malloc(sizeof(node));
p->size = memory.size;
p->address = memory.address;
p->flag[0]='\0';
p->next = NULL;
wfp->next = p;
while(option)
{
printf("\n*****************可变分区管理*****************");
printf("\n * 1.内存管理 *");
printf("\n * 2.内存去配 *");
printf("\n * 0.退出 *");
printf("\n 请输入选项:");
scanf("%d",&option);
if(option == 1)
{
govern(yfp,wfp);
}
else if(option == 2)
{
release(yfp,wfp);
}
}
}
//new malloc 没有真正接触内存
运行结果
样例一:
样例二:
实验总结
①写程序之前的逻辑思路非常重要
②当遇到难理解的地方时一定要多想
③调用函数创建的单链表要注意是否要return,如果是带头节点的可以不用返回值,如果不是带头节点的要返回单链表
④最大的体会是在调用函数中创建的节点和调用函数中定义的变量二者的生存期不同