每个分区有4个数据项,起始地址,大小,状态,进程号,其实地址和大小以KB为单位,状态分为“已分”或“空闲”,进程号:若分区是已分,则填上此分区的进程号,若分区是空闲,则填入?
这里先采用首次适应算法,首次适应算法是将空闲区按起始地址从小到大排序后,会给出3种选择
1.分配空间:输入申请空间的进程号,不能与已经存在的进程号相同,申请空间的大小和阀值,如果分配成功,则重新排序,再次给出3种选择
2.回收空间:则只用输入回收空间的进程号,回收是考虑上下是否邻街空闲区,显示回收后的内存分配情况。
3.结束:直接退出程序
下面是C语言的代码实现
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct memory
{
int startaddress;
int size;
char state[10];
char number[10];
struct memory *next;
struct memory *front;
}FENQU;
FENQU *ready=NULL, *p;
void paixu();
void show(FENQU *p)
{
printf("起始地址 大小 状态 进程号 \n");
printf("%5d\t",p->startaddress);
printf("%8d\t",p->size);
printf("%s \t",p->state);
printf("%s \t\n",p->number);
}
void input()
{
int i,address,size1,n=7;
for(i=1;i<=n;i++)
{
p=(FENQU*)malloc(sizeof(FENQU));
printf("请输入第%d个分区的起始地址:\n",i);
scanf("%d",&address);
p->startaddress=address;
printf("请输入第%d个分区的大小:\n",i);
scanf("%d",&size1);
p->size=size1;
printf("请输入第%d个分区的状态:\n",i);
scanf("%s",p->state);
printf("请输入第%i个分区的进程号:\n",i);
scanf("%s",p->number);
p->next=NULL;
paixu();
}
p = ready;
while (p != NULL)
{
show(p);
p = p->next;
}
}
//按分区的起始位置排序
void paixu()
{
FENQU *first,*second;
int insert=0;
if((ready == NULL) || ((p->startaddress) < (ready->startaddress)))
{
p->next = ready;
ready = p;
}
else
{
first = ready;
second = first->next;
while (second != NULL)
{
if (p->startaddress < second->startaddress)
{
p->next = second;
first->next = p;
insert = 1;
break;
}
else
{
first = first->next;
second = second->next;
}
}
if (insert == 0)
{
first->next = p;
p->next = NULL;
}
}
}
//首次适应算法
FENQU *scsf()
{
int asize,fazhi;
char pcbnumber;
printf("请输入进程号,大小和阀值\n");
scanf("%s",&pcbnumber);
scanf("%d",&asize);
scanf("%d",&fazhi);
FENQU *pretail,*tail,*q;
p=ready;
pretail=tail=p;
while(tail!=NULL)
{
//符合条件,分配内存
if(strcmp(tail->state,"空闲")==0 && tail->size>asize)
{
if(tail->size>asize)
{
q=(FENQU *)malloc(sizeof(FENQU));
q->startaddress=tail->startaddress+tail->size-asize;
q->size=asize;
strcpy(q->state,"已分");
strcpy(q->number,&pcbnumber);
q->next=tail->next;
tail->next=q;
tail->size = tail->size-asize;
strcpy(tail->number,"空闲");
strcpy(tail->number,"?");
break;
}
if(tail->size==asize)
{
strcpy(tail->number,&pcbnumber);
strcpy(tail->state,"已分");
break;
}
}
else
{
pretail=tail;
tail=tail->next;
}
}
//不符合条件,内存分配失败
if(tail==NULL)
{
printf("没有足够的空间,分配失败!\n");
}
return p;
}
//回收
FENQU * huishou()
{
char pcbnumber1;
printf("请输入被回收空间的进程号\n");
scanf("%s",&pcbnumber1);
FENQU *pretail,*tail;
p=ready;
pretail=tail=p;
while(tail!=NULL)
{
if(strcmp(tail->number,&pcbnumber1)==0)
{
if(tail->next!=NULL)
{
if(strcmp(pretail->state,"已分")==0 && strcmp(tail->next->state,"已分")==0)
{
strcpy(tail->state,"空闲");
strcpy(tail->number,"?");
break;
}
//上邻接
if(strcmp(pretail->state,"空闲")==0 && strcmp(tail->next->state,"已分")==0)
{
pretail->next=tail->next;
pretail->size=tail->size+pretail->size;
free(tail);
break;
}
//下邻接
if(strcmp(pretail->state,"已分")==0 && strcmp(tail->next->state,"空闲")==0)
{
if(pretail!=tail)
{
pretail->next=tail->next;
tail->next->size=tail->next->size+tail->size;
tail->next->startaddress=tail->startaddress;
free(tail);
break;
}
else
{
p=tail->next;
tail->next->startaddress=0;
tail->next->size+=tail->size;
break;
}
}
//上下均邻接
if(strcmp(pretail->state,"空闲")==0 && strcmp(tail->next->state,"空闲")==0)
{
pretail->next=tail->next->next;
pretail->size=pretail->size+tail->size+tail->next->size;
free(tail->next);
free(tail);
break;
}
}
else
{
if(strcmp(pretail->state,"已分")==0)
{
strcpy(tail->state,"空闲");
break;
}
else
{
pretail->next=NULL;
pretail->size=pretail->size+tail->size;
free(tail);
break;
}
}
}
pretail=tail;
tail=tail->next;
}
return p;
}
void function()
{
int i;
printf("请选择:(1) 分配空间 (2)回收空间 (3)结束\n");
scanf("%d",&i);
switch(i)
{
case 1:
p=scsf();
printf("分配成功!\n");
while (p != NULL)
{
show(p);
p = p->next;
}
break;
case 2:
p=huishou();
while (p != NULL)
{
show(p);
p = p->next;
}
break;
case 3:
exit(0);
}
function();
}
void main()
{
input();
function();
}