2023年3月16日发(作者:云阳山)连续磁盘存储空间的分配与回收模拟
一、实验目的
深入理解在可变分区管理方式下如何实现磁盘空间的分配与回收。
二、 实验内容
连续磁盘存储空间分配与回收,分配时采用首次适应算法。
三、数据结构及流程
用到的数据结构
①本程序用到的数据结构为空闲表,其组成元素为结构体,其中用来存放空闲表的数组元素定义为:struct
{float address; /*分区起始地址*/
float lenth; /*空闲长度,单位为块*/
int flag; /*空闲表登记栏标志,用“0”表示空栏目,“1”表示未分配*/
} table[n]; /*空闲表*/
其中实型address作为分区起始块号,用于记录个空闲分区的起始块号,在程序开始时,数组第0项address被初始化为0(默认起始块号)其他元素对应项在初始化是不赋值。第二项length表示所对应的项的长度,单位为块,在进程请求磁盘空间时,就是根据这一项大小为其分配合适的地址块,在初始化,第0元素该项被值为1000(默认地址块数),其他项不被置值,最后一项flag用于空闲表登记栏标志,用”0”表示空栏目,表明此项不用于指示磁盘空闲区,则该项其他元素都无效,“1”表示未分配,表明此项其他元素代表磁盘区域,可用于分配给文件,在初始化实第0项被初始化为1,其他项被初始化为0,表示为空。
②另一个结构体ud_table,用于表示已分配表,从中可以看出已分配得的使用情况。其中address表示已分配分区起始块号,length表示已分配分区长度,单位为字节,在初始化使所有项该元素都不赋值,flag表示已分配区登记栏标志,用“0“表示空栏目,表明该项所有元素都无效,若不为0则代表该磁盘区域分配给的文件名,在初始化时由于没有文件,所以全为0。
(2)主程序流程
①系统初始化,输入a的值。
②选择需要的服务类型。如a=1转③,否则若a=2,转④,否则若a=3转⑤,否则退出。
③输入文件的名字和所需空间大小,为其分配磁盘区域。转②。
④输入需要撤销的文件的名字,将其所占有的磁盘回收,转②。
⑤将磁盘空闲表和磁盘分配区表打印,转②。
⑥输入a的值,返回②。
⑦结束。
磁盘分配流程
①输入文件的名字name和所需空间大小length,i=0.
②当i
③在空闲表中找一空标志项j,将其address置为table[i].address,长度为文件所需长度,flag置为文件名。
④将table[i].address置为table[i].address+length,
table[i].length置为table[i].length-length.
(4)磁盘回收流程
①输入想撤销的文件的名字。
②在ud_
table中寻找flag 为name的项。若找不到。则报错。若找到,继续,
③将ud_table[i]的起始块号分别负给head,tail,用于判断磁盘中该区域的上下相临区域是否被占用,若无,则分情况将其合并。
四、源代码
#define n 10
#define m 10
#define area 1000
#define minisize 50
#include "stdio.h"
void main()
{struct
{float address; /* 已分分区起始块号*/
float length; /* 已分分区长度,单位为字节*/
int flag; /*已分配区表登记栏标志,用"0"表示空栏目,已分配用文件名表示*/
}ud_table[n]; /*已分配区表*/
struct
{float address; /*分区起始块号*/
float length; /*空闲区长度,单位为块*/
int flag; /*空闲表登记栏标志,用"0"表示空栏目,"1"表示未分配*/
}table[n]; /*空闲表*/
int i,a,name,j=0,flag=0,right=0,h;
float length,head,tail;
for(i=0;i
ud_table[i].flag=0; /*已分配区表初始化*/
table[0].address=0.0;
table[0].length=1000.0;
table[0].flag=1; /*空闲表初始化*/
for(i=1;i
table[i].flag=0;
printf("请选择服务类型
");
2006-07-06 19:33回复
221.215.123.* 2楼
printf("1 调入新的文件
");
printf("2 收回文件磁盘空间
");
printf("3 打印磁盘分配情况表
");
printf("4 退出
"); /*输出功能提示*/
scanf("%d",&a); /*读入选择的服务 */
while(a!=4)
{
if(a==1) /*若为1则分配磁盘空间*/
{
printf("输入文件名:");
scanf("%d",&name);
printf("输入所需磁盘大小:");
scanf("%f",&length); /*读入文件名字和所需磁盘大小*/
i=0;
while(i
{ if(table[i].flag==1&&table[i].length>=length)
{ break;
}i++;
} /*找到一个合适的空间,分配给文件*/
if(i>=n)
printf("无足够磁盘空间
");/*若磁盘不足,则给于相应的提示*/
el
{while(ud_table[j].flag!=0)
j++;
ud_table[j].address=table[i].address;
ud_table[j].length=length; /*对磁盘取表和已分配区表进行调整*/
ud_table[j].flag=name;
table[i].address=table[i].address+length;
table[i].length-=length;
}
}
el if(a==2)
{ printf("输入想删除的文件名: ");
scanf("%d",&name);
h=0;
for(i=0;i
if(ud_table[i].flag==name)
{ head=ud_table[i].address;
tail=ud_table[i].address+ud_table[i].length;
ud_table[i].flag=0;}
while(table[h].flag!=0) h++;
for(i=0;i
if((table[i].address==tail)&&(table[i].flag==1))
{ tail=tail+table[i].length;
table[i].flag=0;} /*若收回磁盘区域后续磁盘未分配,则将其合并*/
for(j=0;j
if(head==(table[j].address+table[j].length)&&(table[j].flag==1))
{ table[j].length+=(tail-head);
flag=1;
} /*若收回磁盘区域前部未分配,则将其合并*/
if(flag==0)
{ table[h].address=head;
table[h].length=tail-head;
table[h].flag=1;flag=0;}
}
el if(a==3) /*若选择3则打印磁盘分配表*/
{ printf("ud_table
");
printf("起始块号 t长度 t标志
");
for(i=0;i
{ if(ud_table[i].flag!=0)
printf("%d %ft%ft%d
",i,ud_table[i].address,ud_table[i].length,ud_table[i].flag);
}
printf("
table
");
printf(" 起始块号 t长度 t标志
");
for(i=0;i
{ if(table[i].flag==1)
printf(" %d %ft%ft%d
",i,table[i].address,table[i].length,table[i].flag);
}
}
printf("请选择服务类型
");
scanf("%d",&a);
}
}/*结束*/
五、 调试分析及总结
通过这次试验,自己对磁盘可变分区管理的贮存分配回收有了更深的了解,使课本上的知识的到深化,在程序中用了许多if,el语句,对这些语句结构的掌握对编写几条时程序有很大的帮助,由于自己编程及实际经验有限,在编写过程中,对有些环节进行了简化,虽然可以在总体上完成所要求的功能,但一些细节上略显不足,虽然这样,但自己毕竟花费了许多力气,该试验的目的也基本上达到了,就是对课本上相应的知识有了更深的了解,有助于以后更好的学习,收获很大。
六、程序一次测试结果
1 调入新的文件
2 收回文件磁盘
3 打印磁盘分配情况表
4 退出
1输入文件名:1 输入所需磁盘大小:100
请选择服务类型:1
输入文件名:2 输入所需磁盘大小:100
请选择服务类型:1
输入文件名:3 输入所需磁盘大小:100
请选择服务类型:3
ud_table
起始块号 长度 标志
0 0.000000 100.000000 1
1 100.000000 100.000000 2
2 200.000000 100.000000 3
table
起始块号 长度 标志
0 300.000000 700.000000 1
请选择服务类型:2
输入想删除的文件名: 2
请选择服务类型:3
ud_table
起始块号 长度 标志
0 0.000000 100.000000 1
2 200.000000 100.000000 3
table
起始块号 长度 标志
0 300.000000 700.000000 1
1 100.000000 100.000000 1
请选择服务类型: 2
输入想删除的文件名: 3
请选择服务类型:3
ud_table
起始块号 长度 标志
0 0.000000 100.000000 1
table
起始块号 长度 标志
1 100.000000 900.000000 1
请选择服务类型:4
信息学院
计本03级2班
于庆