实验 可变分区内存分配首次适应算法模拟
发布时间:2024-11-25
发布时间:2024-11-25
实验 可变分区内存分配首次适应算法模拟
一、实验目的:
模拟内存分配, 了解并掌握动态分区分配中所用的数据结构、分区分配算法,深刻理解
首次适应内存分配算法。
二、实验内容:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int const total= 200 ; //内存总数
int const beginaddress = 20;//初次分配起始地址
struct Block
{
int addr; //块的起始地址
int size; // 块的大小
int flag; //块的分配状态 1:代表已分配 0:代表未分配;
}block[100];
int count=0; //块的个数,初值为0,分配一个则加1,减少一个则减1
void display() //显示所有块的模块
{
int i;
printf(" 目前内存情况\n");
printf("-------------------------------------------------------------------------------- \n");
printf(" 块号 起始地址 大小 分配状态\n");
for(i=1;i<=count;i++)
{
printf(" %d %d
",i,block[i].addr,block[i].size);
if (block[i].flag==0)
printf("未分配\n");
else
printf("已分配\n");
}
printf("-------------------------------------------------------------------------------- \n");
}
void jinchengFirstEnter() //首次初始化分配模块
{ %d
printf("内存总数为%d 第一次分配从 %d 开始\n",total,beginaddress);
int i=1;
int size;
int geshu;
printf("请输入要初次调入内存的进程的个数:");
scanf("%d",&geshu);
while(i<=geshu)
{
printf("请输入第%d个进程的大小:",i);
scanf("%d",&size);
count++;
if (count==1)
{block[count].addr=beginaddress ;}
else
{ block[count].addr=block[count-1].addr+block[count-1].size;}
block[count].size=size;
block[count].flag=1;
i++;
}
count++;
block[count].addr=block[count-1].addr+block[count-1].size;
block[count].flag=0;
block[count].size=total-block[count].addr;
}
void jinchengEnter()
{
//自己编写,采用首次适应算法
}
void jinchengExit() //作业调出内存模块
{ int kuaihao;
printf("请输入要调出内存的块号:");
scanf("%d",&kuaihao);
if(block[kuaihao].flag==0)
printf("该块内存是空闲的,无需调出\n");
else
{ // 将该块设为空闲,就是将该块的flag设为0,
//还考虑了该块的下一块如果是空闲的,则将这两块合并为一块,总块数减1
//如果要考虑该块的前一块是空闲,则将这两块合并为一块,总块数减1,如何改
代码?
block[kuaihao].flag=0;
if(block[kuaihao+1].flag==0)
{
block[kuaihao].size=block[kuaihao].size+block[kuaihao+1].size;
for(int i=kuaihao+2;i<=count;i++)
block[i-1]=block[i];
block[count].size=0;
block[count].flag=0;
block[count].addr=0;
count--;
}
}
display();
}
void main()
{
int flag=0,select;
jinchengFirstEnter();
display();
while(flag==0)
{
printf(" 请输入相应操作\n");
printf(" 1. 进程进入内存 \n");
printf(" 2. 进程退出内存\n");
printf(" 3. 显示当前状态\n");
printf(" 4. 退出");
printf("\n \n 请选择:");
scanf("%d",&select);
switch(select)
{
case 1:jinchengEnter();break;
case 2:jinchengExit();break;
case 3:display();
break;
case 4:flag=1;break;
default:
printf("选择错误,请重新选择");
}
}
}
要求:
1. 仔细研读上述代码,体会可变分区分配的模拟实现,实验报告上描述出
jinchengFirstEnter()函数的实现思想,
2. jinchengFirstEnter()函数没有考虑输入的数据超过范围的情况,请完善该函数
3. 在进程退出函数jinchengExit()中考虑不全面,具体看函数中的描述,能否改写使得
函数完整?
下面是附加题。
4. 请自己实现jinchengEnter()函数,该函数是模拟某进程进入内存,按首次适应算法寻
找空闲空间
函数功能提示:
首先输入要调入内存的进程的大小。然后在block数组中找未分配且比该进程大的块,
如找到的块和进程一样大,直接将该块设为已分配,如比进程大,该块要分为两块,
一块已分配,一块空闲,并且后面的块依次后移一位。
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int const total= 200 ; //内存总数
int const beginaddress = 20;//初次分配起始地址
struct Block
{
int addr; //块的起始地址
int size; // 块的大小
int flag; //块的分配状态 1:代表已分配 0:代表未分配;
}block[100];
int count=0; //块的个数,初值为0,分配一个则加1,减少一个则减1
void display() //显示所有块的模块
{
int i;
printf(" 目前内存情况\n");
printf("-------------------------------------------------------------------------------- \n");
printf(" 块号 起始地址 大小 分配状态\n");
for(i=1;i<=count;i++)
{
printf(" %d %d %d
",i,block[i].addr,block[i].size);
if (block[i].flag==0)
printf("未分配\n");
else
printf("已分配\n");
}
printf("-------------------------------------------------------------------------------- \n");
}
void jinchengFirstEnter() //首次初始化分配模块
{
printf("内存总数为%d 第一次分配从 %d 开始\n",total,beginaddress);
int i=1;
int size;
int geshu;
int total1=0;
printf("请输入要初次调入内存的进程的个数:");
scanf("%d",&geshu);
while(i<=geshu)
{ printf("请输入第%d个进程的大小:",i);
scanf("%d",&size);
total1=size+total;
if(size>20&&total1>200)
{
printf("重新输入");
scanf("%d",&size);
}
total1=size+total;
count++;
if (count==1)
{block[count].addr=beginaddress ;}
else
{ block[count].addr=block[count-1].addr+block[count-1].size;}
block[count].size=size;
block[count].flag=1;
i++;
}
count++;
block[count].addr=block[count-1].addr+block[count-1].size;
block[count].flag=0;
block[count].size=total-block[count].addr;
}
void jinchengEnter()
{
//自己编写,采用首次适应算法
}
void jinchengExit() //作业调出内存模块
{ int kuaihao;
printf("请输入要调出内存的块号:");
scanf("%d",&kuaihao);
if(block[kuaihao].flag==0)
printf("该块内存是空闲的,无需调出\n");
else
{ // 将该块设为空闲,就是将该块的flag设为0,
//还考虑了该块的下一块如果是空闲的,则将这两块合并为一块,总块数减1
//如果要考虑该块的前一块是空闲,则将这两块合并为一块,总块数减1,如何改
代码?
block[kuaihao].flag=0;
if(block[kuaihao+1].flag==0)
{
block[kuaihao].size=block[kuaihao].size+block[kuaihao+1].size;
for(int i=kuaihao+2;i<=count;i++)
block[i-1]=block[i];
block[count].size=0;
block[count].flag=0;
block[count].addr=0;
count--;
}
if(block[kuaihao-1].flag==0)
{
block[kuaihao].size=block[kuaihao].size+block[kuaihao-1].size;
for( int i=kuaihao+2;i<=count;i++)
block[i+1]=block[i-1]; block[count].size=0;
block[count].flag=0;
block[count].addr=0;
count--;
}
}
display();
void main()
{
int flag=0,select;
jinchengFirstEnter();
display();
while(flag==0)
{
printf(" 请输入相应操作\n"); printf(" 1. 进程进入内存 \n"); printf(" 2. 进程退出内存\n"); printf(" 3. 显示当前状态\n"); printf(" 4. 退出");
printf("\n \n 请选择:");
scanf("%d",&select);
switch(select)
{
case 1:jinchengEnter();break;
case 2:jinchengExit();break;
case 3:display();
break;
case 4:flag=1;break;
default:
printf("选择错误,请重新选择");
}
}
}