实验报告
班级: 计算机B191 学号: 2019537130 姓名: 陈力源 日期: 5月19日
⒈ 实验题目
主存储器空间分配实验。
2.实验要求
编写一段程序来模拟可变分区管理方法。要求能通过文件形式定义空闲区表;能随意输入作业及需要分配的空间;能分别使用首次适应算法、最佳适应算法和最坏适应算法对输入的作业进行空间分配;能显示系统空闲表和已分配空间表。
3. 实验目的
通过首次适应算法、最佳适应算法和最坏适应算法实现主存空间的分配,可以使读者可好地理解存储分配算法。
⒋ 实验原理分析
⑴可变分区方式是按作业需要的主存空间大小来分区。当装入一个作业时,首先要查看是否有足够的空闲空间来分配,若有则按指定的分配方式进行分配;否则作业不能装入。随着作业的装入和撤离主存空间被分为若干个大大小小的不连续的区间,为了表明各区间的状态可以用一个内存分区表如表1所示来表示。
表1 内存分区表
| 起始地址 |
长度 |
标志 |
| 120k |
20k |
作业1 |
| 200k |
50k |
空闲 |
这样我们可以定义一个如下的结构表示内存分区信息。
typedef struct node
{
int start; //起始地址
int length; //长度
char tag[20]; //标志
}job;
⑵可变分区的三种算法就是为作业分配主存空间的方法。
● 首次适应算法:在空闲区间中查询满足作业需要的空间,并将作业装入第一个满足条件的空间中去。
● 最佳适应算法:在空闲区间中查询满足作业需要的空间,并将作业装入满足条件的空闲空间中最小的一个空间中去。
● 最坏适应算法:在空闲区间中查询满足作业需要的空间,并将作业装入满足条件的空闲空间中最大的一个空间中去。
从三种算法的说明可以看出,分配空间的过程主要可以分两步:
● 查询所有满足作业需求的空间块。
● 按照指定的算法将作业装入空间块中。
⑶在操作的最初主存空间实际就是一个大的空闲区,不涉及到如何分配的问题。为直接模拟运行一段时间后主存中出现了多个空闲块的状态,题目要求从一个文件读入空闲区表。在这里我们可以设计一个空闲区表文件的结构为如表2所示:
表2 空闲区表
| 起始地址 |
长度 |
| 200k |
50k |
| … |
… |
这样也可以方便地将空闲表一次读入程序中,而不必再一个个的输入。
⑷主要变量及函数说明如表3所示。
表3 变量与函数说明表
| typedef struct node |
内存块结构 |
| job frees |
空闲区表 |
| job occupys |
已分配区表 |
| free_quantity |
空闲区数量 |
| occupy_quantity |
已分配区数量 |
| void initial() |
初始化函数 |
| int readData() |
从文件读入空闲表函数 |
| void sort() |
排序空闲表 |
| void view() |
显示分区信息 |
| void earliest() |
最先适应分配算法 |
| void excellent() |
最优适应分配算法 |
| void worst() |
最坏适应算法 |
| mem.txt |
空闲表文件 |
5.实验代码清单
#include "stdafx.h"
#include "stdafx.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXJOB 200 // 定义存储数据最大值
typedef struct node // 内存块结构
{
int start;
int length;
char tag[20];
}job;
job frees[MAXJOB]; // 定义空闲区表
int free_quantity; // 空闲区块数
job occupys[MAXJOB]; // 定义已分配区表
int occupy_quantity; // 已分配区块数
// 初始化函数
void initial()
{
int i;
for (i = 0; i < MAXJOB; i++)
{
frees[i].start = -1;
frees[i].length = 0;
strcpy(frees[i].tag, "free"); // 定义所有块为空闲块
occupys[i].start = -1;
occupys[i].length = 0;
strcpy(occupys[i].tag, ""); // 已分配块为 0
}
free_quantity = 0;
occupy_quantity = 0;
}
// 读数据函数,从文件中读入空闲表的设置
int readData()
{
FILE * fp;
if ((fp = fopen("D:\\mem.txt", "r")) == NULL)
{
printf(" 错误, 文件不存在\n");
}
else
{
while (!feof(fp))
{ // 打开文件读入空闲表信息
fscanf(fp, "%d %d", & frees[free_quantity].start, & frees[free_quantity].length);
free_quantity++;
}
return 1;
}
return 0;
}
// 排序空闲表
void sort()
{
int i, j, p;
for (i = 0; i < free_quantity - 1; i++)
{
p = i;
for (j = i + 1; j < free_quantity; j++)
{
if (frees[j].start < frees[p].start)
{
p = j;
}
}
if (p != i)
{
frees[free_quantity] = frees[i];
frees[i] = frees[p];
frees[p] = frees[free_quantity];
}
}
}
// 显示函数
void view()
{
int i;
printf(" 空闲表 :\n"); // 显示空闲表
printf(" 起始地址 长度 状态\n");
for (i = 0; i < free_quantity; i++)
{
printf("%8d\t%4d\t%s\n", frees[i].start, frees[i].length, frees[i].tag);
}
getchar();
}
void prin()
{
printf(" 当前已分配表 :\n");
printf(" 起始地址 长度 占用作业名 \n");
for (int i = 0; i < occupy_quantity; i++)
{ // 显示已分配表
printf("%8d\t%4d\t%s\n", occupys[i].start, occupys[i].length, occupys[i].tag);
}
}
// 最先适应分配算法
void earliest()
{
char job_name[10];
int job_length;
int i, j, flag, t;
printf(" 请输入新申请内存空间的作业名 :");
scanf("%s", & job_name);
printf(" 请输入新申请内存空间的大小 :");
scanf("%d", & job_length);
flag = 0;
for (i = 0; i < free_quantity; i++)
{ // 顺序查找满足条件的空间
if (frees[i].length >= job_length)
{
flag = 1;
}
}
if (flag == 0)
{ // 没找到满足的空间
printf("\n 当前没有能满足你申请长度的空闲内存 , 请稍候再试 \n");
}
else
{ // 找到了满足的空间
t = 0;
i = 0;
while (t == 0)
{
if (frees[i].length >= job_length)
{
t = 1;
}
i++;
}
i--;
occupys[occupy_quantity].start = frees[i].start; // 分配满足条件的空间
strcpy(occupys[occupy_quantity].tag, job_name);
occupys[occupy_quantity].length = job_length;
occupy_quantity++;
if (frees[i].length > job_length)
{
frees[i].start += job_length;
frees[i].length -= job_length;
}
else
{
for (j = i; j < free_quantity - 1; j++)
{
frees[j] = frees[j + 1];
}
free_quantity--;
printf(" 内存空间成功 !\n");
}
}
}
// 最优适应分配算法
void excellent()
{
char job_name[20];
int job_length;
int i, j, flag, t;
printf(" 请输入新申请内存空间的作业名 :");
scanf("%s", & job_name);
printf(" 请输入新申请内存空间的大小 :");
scanf("%d", & job_length);
flag = 0;
for (i = 0; i < free_quantity; i++)
{
if (frees[i].length >= job_length)
{
flag = 1;
}
}
if (flag == 0)
{
printf("\n 当前没有能满足你申请长度的空闲内存 , 请稍候再试 \n");
}
else
{
t = 0;
i = 0;
while (t == 0)
{
if (frees[i].length >= job_length)
{
t = 1;
}
i++;
}
i--;
for (j = 0; j < free_quantity; j++)
{ // 找到满足条件的最小空闲空间
if ((frees[j].length >= job_length) && (frees[j].length < frees[i].length))
{
i = j;
}
}
occupys[occupy_quantity].start = frees[i].start; // 分配空闲空间
strcpy(occupys[occupy_quantity].tag, job_name);
occupys[occupy_quantity].length = job_length;
occupy_quantity++;
if (frees[i].length > job_length)
{
frees[i].start += job_length;
frees[i].length -= job_length;
}
else
{
for (j = i; j < free_quantity - 1; j++)
{
frees[j] = frees[j + 1];
}
free_quantity--;
printf(" 内存空间成功 !\n");
}
}
}
// 最坏适应算法
void worst()
{
char job_name[20];
int job_length;
int i, j, flag, t;
printf(" 请输入新申请内存空间的作业名 :");
scanf("%s", & job_name);
printf(" 请输入新申请内存空间的大小 :");
scanf("%d", & job_length);
flag = 0;
for (i = 0; i < free_quantity; i++)
{
if (frees[i].length >= job_length)
{
flag = 1;
}
}
if (flag == 0)
{
printf("\n 当前没有能满足你申请长度的空闲内存 , 请稍候再试 \n");
}
else
{
t = 0;
i = 0;
while (t == 0)
{
if (frees[i].length >= job_length)
{
t = 1;
}
i++;
}
i--;
for (j = 0; j < free_quantity; j++)
{ // 找到满足条件的最大空闲空间
if ((frees[j].length >= job_length) && (frees[j].length > frees[i].length))
{
i = j;
}
}
occupys[occupy_quantity].start = frees[i].start; // 分配空闲空间
strcpy(occupys[occupy_quantity].tag, job_name);
occupys[occupy_quantity].length = job_length;
occupy_quantity++;
if (frees[i].length > job_length)
{
frees[i].start += job_length;
frees[i].length -= job_length;
}
else
{
for (j = i; j < free_quantity - 1; j++)
{
frees[j] = frees[j + 1];
}
free_quantity--;
printf(" 内存空间成功 !\n");
}
}
}
// 主函数
void main()
{
int flag = 0;
int t = 1;
int chioce = 0;
initial(); // 初始化
flag = readData(); // 读空闲表文件
while (flag == 1)
{
sort(); // 排序
// 显示菜单
printf(" 动态分区算法 \n");
printf("1. 显示空闲表和分配表 \n2. 最先适应法 \n3. 最优适应法 \n4. 最坏适应法 \n0. 退出\n");
printf(" 请选择 :");
scanf("%d", & chioce); // 输入选择的菜单项
switch (chioce)
{
case 1:
// 显示空闲表和分配表
view();
break;
case 2:
// 调用最先适应法
earliest();
prin();
break;
case 3:
// 最优适应法
excellent();
prin();
break;
case 4:
// 最坏适应法
worst();
prin();
break;
case 0:
// 退出
flag = 0;
break;
default:
printf("\n 选择错误 !\n");
}
}
}
空闲表
最先适应
最优适应
最坏适应