0
空闲块数k
1
空闲块号1
2
空闲块号2
K
空闲块号k
当第一项内容为“0"时,则第二项起指出的空闲块是最后一组。
(2)现模拟UNIX系统的空闲块成组链接,假定共有8块可供使用,每3块为一组,则空闲块成组链接的初始状态为:
开始时,空闲块号是顺序排列的,但经若干次的分配和归还操作后,空闲块的链接就未必按序排列了。
用二维数组A:
array[0…M—1]ofarray[0…n-1]来模拟管理磁盘空间,用A[i]表示第I块,第0块A[0]作为专用块。
(3)成组链接的分组情况记录在磁盘物理块中,为了查找链接情况,必须把它们读入主存,故当磁盘初始化后,系统先将专用块内容复制到主存中。
定义一个数组MA存放专用块内容,即MA:
=A[0].申请一块磁盘空间时,查MA,从中找出空闲块号,当一组的空闲块只剩第一块时,则应把该块中指出的下一组的空闲块数和块号复制到专用块中,然后把该块分配给申请者.当一组的空闲块分配完后则把专用块内容(下一组链接情况)复制到主存,再为申请者分配.分配算法如图6—1。
图6-1采用成组链接的分配算法
(4)归还一块时给出归还的块号,叵当前组不满规定块数时,将归还块登记入该组;若当前组已满,则另建一新组,这时归还块作为新一组的第一块,应把主存中登记的一组链接情况MA复制到归还块中,然后在MA重新登记一个新组.归还一块的算法如图6-2。
图6—2采用成组链接的回收算法
(5)设计分配和归还磁盘空间的程序,能显示或打印分配的磁盘空间的块号,在完成一次分配或归还后能显示或打印各空闲块组的情况(各组的空闲块数和块号)。
本实习省去了块号与物理地址之间的转换工作,而在实际的系统中必须进行块号与物理地址的转换工作。
(6)运行你所设计的程序,假定空闲块链接的初始状态如提示
(2),现先分配4块,再依次归还第2块和第6块。
把执行后分配到的块号依次显示或打印出来,且显示或打印空闲块组的情况。
在上次执行的基础上继续分配3块,然后归还第1块,再申请5块,显示或打印依次分配到的块号及空闲块组情况。
四、相关数据结构及说明
structfreeblock{
intFBbegin;//起始空闲块号
intnum;//空闲块数
charstate;//状态
structfreeblock*next;}
struct filetowrite {
char name[10];//文件名
int size;//文件大小
int addr_cylinder;//装入磁盘的首地址_柱面号
int addr_track;//装入磁盘的首地址_磁道号
int addr_note;//装入磁盘的首地址_物理记录号
struct filetowrite *next; }
六、源代码及注释
1、题一源代码:
#include〈stdlib.h>
#include〈stdio。
h>
int getmalloc()//分配磁盘空间 {
int flag=0;
struct freeblock *p=FBhead;
struct filetowrite *File;
File=(struct filetowrite *)malloc(sizeof(struct filetowrite));
printf("输入要装入的文件名:
”);
scanf("%s",File—〉name);
printf("输入所需的磁盘空间大小:
");
scanf("%d”,&File—>size);
for(p=FBhead->next;p!
=NULL;p=p—〉next)
if((File-〉size)<=(p-〉num))//分配空间
{
flag=1;
File—>addr_cylinder=((p—〉FBbegin)/6)/20;
File->addr_track=((p->FBbegin)/6)%20;
File—>addr_note=(p—〉FBbegin)%6;
File—>next=Filehead-〉next;//加入文件链表
Filehead—>next=File;
if((File—〉size)〈(p—〉num))//修改该快的起始地址和块数
{
p—〉FBbegin=p-〉FBbegin+File—>size;
p->num=p—〉num—File—〉size; }
else p-〉state='U';
break; }
if(flag==0)
printf(”抱歉!
目前没有足够的磁盘空间分配给该文件。
\n”);
else {
printf(”分配磁盘成功!
\n该文件的物理地址:
\n柱面号\t磁道号\t物理块号\n ”);
printf(" %d\t %d\t %d\n",File-〉addr_cylinder,File—>addr_track,File—〉addr_note); } }
int deletelfree()//回收磁盘空间 {
char name[10]; int flag=0;
struct filetowrite *p;
printf("输入要删除的文件名:
”);
scanf(”%s",&name);
for(p=Filehead;p->next!
=NULL;p=p->next)
{
if(strcmp(p-〉next—>name,name)==0)//找到该文件
{
flag=1;
int funion=0,nunion=0;
int m=p->next—〉addr_cylinder;
int n=p—>next-〉addr_track;
int k=p-〉next-〉addr_note;
int addr=(m*20+n)*6+k;//起始空闲块号
int tail=p—〉next-〉size+addr;
struct freeblock *pnode,*qnode,*tnode,*snode;
pnode=FBhead-〉next;
while(pnode!
=NULL)//先考虑和后面的部分或许有合并的情况
{
if((pnode—>FBbegin)==tail)
{
pnode-〉FBbegin=addr;
pnode->num=pnode—〉num+p—>next->size;
nunion=1;
break; }
pnode=pnode-〉next; }
qnode=FBhead->next;
while(qnode!
=NULL)//再考虑是否和前面的可以合并
{
if((qnode—>FBbegin+qnode—>num)==addr)
{
if(nunion==0)
{
qnode—>num=qnode—〉num+p—>next—〉size;
funion=1;
break; }
else
{
qnode->num=qnode—〉num+pnode—>num; t
node=FBhead;
while(tnode—>next!
=pnode)
tnode=tnode—〉next;
tnode->next=pnode-〉next;
free(pnode);
funion=1;
break;
}
}
qnode=qnode-〉next; }
if(funion==0&&nunion==0)//若没有和前面的或后面的进行合并,则新建一个表目
{
snode=(struct freeblock *)malloc(sizeof(struct freeblock));
snode->FBbegin=addr;
snode-〉num=p-〉next—〉size;
snode—>state='F’;
if(FBhead->next==NULL)
{
FBhead—〉next=snode;
snode—〉next=NULL;
}
else
{
snode->next=FBhead->next;
FBhead—〉next=snode; } }
struct filetowrite *q;
q=p-〉next;//除该文件
p—>next=p—>next-〉next;
free(q); break; } }
if(flag==0)
printf(”没有该文件!
\n”);
else {
printf(”文件删除成功!
\n”); }
int dispfree()//显示磁盘空闲区表
{
int i=1;
struct freeblock *p=FBhead;
printf("\n磁盘空闲区表\n”);
printf("序号\t起始空闲块号\t空闲块个数\t 状态\n");
for(p=FBhead->next;p!
=NULL;p=p->next)
{
if((p->state)==’F')
printf(" %d\t %d\t\t %d\t\t未分配\n",i++,p—>FBbegin,p—〉num);
else
printf(" %d\t\t\t\t\t空表目\n",i++); } }
int dispfile()
{
char name[10];
struct filetowrite *p=Filehead; printf(”输入要查看的文件名:
");
scanf(”%s”,&name);
for(p=Filehead—〉next;p!
=NULL;p=p—〉next)
{
if(strcmp(p—>name,name)==0) {
printf("该文件的物理地址:
\n柱面号\t磁道号\t物理块号\n ");
printf(” %d\t %d\t %d\n",p->addr_cylinder,p-〉addr_track,p—〉addr_note); break; } }
if(p==NULL)
printf(”没有该文件!
\n”); }
int main() {
int n,i,A[MAX],B[MAX];//A[MAX]表示起始空闲块号,B[MAX]表示空闲块个数
char ch;
struct freeblock *pnew;
FBhead=(struct freeblock *)malloc(sizeof(struct freeblock));
FBhead-〉next=NULL;
printf("输入磁盘空闲区个数:
”);
scanf(”%d”,&n);
for(i=1;i<=n;i++) {
pnew=(struct freeblock *)malloc(sizeof(struct freeblock));
pnew—〉next=NULL;
pnew—>next=FBhead—>next;
FBhead—>next=pnew;
printf("起始空闲块号:
");
scanf("%d”,&pnew—〉FBbegin);
printf(”空闲块个数:
”);
scanf("%d”,&pnew—〉num); pnew-〉state=’F'; pnew=pnew->next; }
Filehead=(struct filetowrite *)malloc(sizeof(struct filetowrite));
Filehead-〉next=NULL;
do {
system("cls");
printf(”\n\t\t ********** 主菜单 **********\n\n");
printf(”\t\t\t1。
新建文件\n");
printf("\t\t\t2。
删除文件\n”);
printf("\t\t\t3.查看磁盘\n");
printf(”\t\t\t4。
查看文件\n");
printf(”\t\t\t5.退出\n"); printf("请选择:
”);
scanf(”%c”,&ch);
switch(ch) {
case ’1’:
getmalloc();system("pause");break;
case '2':
deletelfree();system(”pause”);break;
case ’3’:
dispfree();system("pause");break;
case '4':
dispfile();system("pause”);break;
case '5':
exit
(1);break;
default:
printf("输入错误!
请重新输入。
\n");
}
printf(”\n");
getchar(); }
while(ch!
=4);
return 0;
2、题二源代码:
#include h〉
#include h>
void Initbitmap(in