⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 内存可变分区模拟.c

📁 模拟操作系统中的内存分区分配
💻 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 + -