作業系統可變分割槽用C語言實現按首次適應演算法分配記憶體
阿新 • • 發佈:2019-01-01
每個分割槽有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();
}