📄 内存可变分区模拟.c
字号:
#include <stdio.h>
#include<malloc.h>
#include<string.h>
typedef struct space //////采用链表结构,每一个结点对应一个分区
{
long sta_addr; ////////////////////////////分区的首地址
long length; ////////////////////////////分区的长度
char sign[16];/////分区的文字说明,进程如名称,状态等等
struct space *next;
}space,*point;
point p,q,r,s,t;
int i,j,k,l,m,n;
long total; ///////////////////////////////内存总量
point used_p,empt_p;////////////////////////两条链表的头指针
space usedhead,empthead;///////////////////两条链表的头结点
long size=0;
char Sign[16]="\0";
long Sta_addr=0;
void show(point a)//////////////////////打印区表
{
if(a!=NULL)
{
printf("%ld\t\t%ld\t\t",a->sta_addr,a->length);
printf(a->sign);
printf("\n");
show(a->next);////////递归显示各个结点
}
}
void first()///////////____________________模拟首次适应申请内存
{
printf("首次适应,你需要申请多少空间?(单位:K):\t");
scanf("%d",&size);
////////////////////////////处理空闲区表
p=empt_p;
for(;;)
{
if(p->next==NULL) break;
else if(p->next->length>=size)break;
else p=p->next;
}
if(p->next==NULL){printf("\t没有足够空间可以分配!!!\n");return;}
else
{
printf("请输入进程名称(仅限16个以内的字母,不能和已有进程重名):\t");
scanf("%s",Sign);/////////////////////////////////////输入进程名
Sta_addr=p->next->sta_addr;//内存分区头地址通过Sta_addr传送
p->next->sta_addr=p->next->sta_addr+size;
p->next->length=p->next->length-size;
}
if(p->next->length==0){q=p->next;p->next=p->next->next;free(q);}
//如果一个空间刚刚被完全申请,剩下的空间为零,则
//////在空闲区表中删除这一项
////////在已分区表中登记新进程
q=(space *)malloc(sizeof(space));
q->length=size;
q->next=NULL;
q->sta_addr=Sta_addr;//内存分区头地址通过Sta_addr传送
///////////////////////////以下是把进程名给标志
for(i=0;i<16;i++)
{
q->sign[i]=Sign[i];
if(Sign[i]=='\0')break;
}
p=used_p;
for(;;)
{
if(p->next&&p->next->sta_addr<Sta_addr)p=p->next;
else break;
}
q->next=p->next;
p->next=q;
}
void best()///////////////__________________模拟最佳适应申请内存
{
printf("最佳适应,请输入你要求的内存量(单位:k):\t");
scanf("%d",&size);
////////////////////////////处理空闲区表
r=& empthead;
for(;;)
{
if(r->next==NULL) break;
else if(r->next->length>=size)break;
else r=r->next;
}
if(r->next==NULL){printf("\n\t没有足够空间可以分配!!!!\n");return;}
else
printf("请输入进程名称(仅限字母,16个以内,不能和已有进程重名):\t");
scanf("%s",Sign);
p=r;
for(;;)
{
r=r->next;
if (r->next==NULL)
break;
if(r->next->length>=size&&r->next->length<p->next->length)
p=r;
}
Sta_addr=p->next->sta_addr;//内存分区头地址通过Sta_addr传送
p->next->sta_addr=p->next->sta_addr+size;
p->next->length=p->next->length-size;
if(p->next->length==0){q=p->next;p->next=p->next->next;free(q);}
//如果一个空间刚刚被完全申请,剩下的空间为零,则
//////则在空闲区表中删除这一项
////////在已分区表中登记新进程
q=(space *)malloc(sizeof(space));
q->length=size;
q->next=NULL;
q->sta_addr=Sta_addr;//内存分区头地址通过Sta_addr传送
///////////////////////////以下是把进程名给标志
for(i=0;i<16;i++)
{
q->sign[i]=Sign[i];
if(Sign[i]=='\0')break;
}
p=used_p;
for(;;)
{
if(p->next&&p->next->sta_addr<Sta_addr)p=p->next;
else break;
}
q->next=p->next;
p->next=q;
}
void worst()//////////______________________模拟最坏适应申请内存
{
printf("最坏适应,你要多大的内存?\t");
scanf("%d",&size);
////////////////////////////处理空闲区表
r=empt_p;
for(;;)
{
if(r->next==NULL) break;
else if(r->next->length>=size)break;
else r=r->next;
}
if(r->next==NULL){printf("\t没有足够空间可以分配!!!\n");return;}
else
printf("进程名称是(字母,少于17个,不能和已有进程重名):\t");
scanf("%s",Sign);
p=r;
for(;;)
{
r=r->next;
if (r->next==NULL)
break;
if(r->next->length>p->next->length)
p=r;
}
Sta_addr=p->next->sta_addr;//内存分区头地址通过Sta_addr传送
p->next->sta_addr=p->next->sta_addr+size;
p->next->length=p->next->length-size;
if(p->next->length==0){q=p->next;p->next=p->next->next;free(q);}
//如果一个空间刚刚被完全申请,剩下的空间为零,则
////则在空闲区表中删除这一项
////////在已分区表中登记新进程
q=(space *)malloc(sizeof(space));
q->length=size;
q->next=NULL;
q->sta_addr=Sta_addr;//内存分区头地址通过Sta_addr传送
///////////////////////////以下是用循环把进程名给标志
for(i=0;i<16;i++)
{
q->sign[i]=Sign[i];
if(Sign[i]=='\0')break;
}
p=used_p;
for(;;)
{
if(p->next&&p->next->sta_addr<Sta_addr)p=p->next;
else break;
}
q->next=p->next;
p->next=q;
}
void giveback()/////////_________________________模拟释放内存
{
printf("请输入你想结束的进程的名称:\t");
scanf("%s",Sign);
q=used_p;
p=q->next;
for(;;)
{
if(p==NULL)break;
for(i=0;i<16;)////////////////循环对比字符数组
{
if(p->sign[i]=='\0'&&Sign[i]=='\0') break;
if(p->sign[i]!=Sign[i]) break;
i++;
}
if(p->sign[i]=='\0'&&Sign[i]=='\0') break;//名字匹配成功
q=q->next;
p=q->next;
}
if(p==NULL)//////////////////出现进程不存在情况,提示并退出
{
printf("\n不存在这样的进程,请检查确认\n");
return;
}
/////////////////////////存在这样的进程,把其空间归还
q->next=p->next;
////////以下是在空闲区表中适当的位置登记被释放的空间//////
for(q=empt_p;;)
{
if(q->next==NULL) break;
if(q->next->sta_addr>p->sta_addr) break;
q=q->next;
}
p->next=q->next;
q->next=p;
strcpy(p->sign,"Aviable");/////////////标志改变
///////////////////////////////把相邻的空闲块联接成大块
for(p=empthead.next;;)
{
if(p->next==NULL)break;
if(p->sta_addr+p->length==p->next->sta_addr)
{
p->length=p->length+p->next->length;
q=p->next;
p->next=p->next->next;
free(q);
continue;
}
p=p->next;
}
}
main()
{
/////////////初始化两条链表usedhead,empthead,帮助简化处理
used_p=&usedhead;
empt_p=&empthead;
empt_p->next=NULL;
used_p->next=NULL;
printf("请设定模拟内存的总大小(单位:K):\n");
scanf("%ld",&total);
s=(space *)malloc(sizeof(space));
s->length=total;
s->sta_addr=0;
s->next=NULL;
strcpy(s->sign,"Aviable");
empthead.next=s;
for(;;)
{
system("cls");
//clrscr();//一定要放在定义变量后
printf("内存的分配情况:\n\n");
if(usedhead.next==NULL)printf("没有进程\n");
else
{
printf("已分配区表:\n");
printf("首地址\t\t长度\t\t进程名称\n");
show(usedhead.next);
}
printf("\n");
if(empthead.next==NULL)printf("没有空闲区\n");
else
{
printf("空闲区表:\n");
printf("首地址\t\t长度\t\t标志\n");
show(empthead.next);
}
printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
printf(" 1.首次适应算法,2.最佳适应算法,3.最坏适应算法,4.回收分区,5.结束模拟\n你选择:\t");
scanf("%d",&j);
switch(j)
{
case 1: first();break;
case 2:best();break;
case 3:worst();break;
case 4:giveback();break;
case 5:exit(0);break;
default:exit(0);
}
printf("*******************************************************************************\n");
printf("执行上述操作后内存的分配情况:\n\n");
if(usedhead.next==NULL)printf("没有进程");
else
{
printf("已分配区表:\n");
printf("首地址\t\t长度\t\t进程名称\n");
show(usedhead.next);
}
printf("-------------------------------------------------------------------------------\n");
if(empthead.next==NULL)printf("没有进程");
else
{
printf("空闲区表:\n");
printf("首地址\t\t长度\t\t状态\n");
show(empthead.next);
}
printf("-------------------------------------------------------------------------------\n");
printf("按任意键刷新:");
getch();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -