西安邮电大学
(计算机学院)
课内实验报告
实验名称:内存分配与回收
专业名称:计算机科学与技术
班级:计科1503
学生姓名:段唐奇
学号(8位):01131652
指导教师:张德慧
实验日期:2016年5月23日---2016年6月6日
一. 实验目的及实验环境
1.实验目的
掌握内存分配FF,BF,WF策略及实现的思路;
掌握内存回收过程及实现思路;
实现内存的申请、释放的管理程序,调试运行,总结程序设计中出现的问题并找出原因,写出实验报告。
2.实验环境
(1)硬件
CPU:I7-6500
内存:8G
显示器:笔记本显示器
硬盘空间:1TB
(2)软件
虚拟机名称及版本:Vmware
操作系统名称及版本:Ubuntu Kylin 16.04
编译器:gcc
二. 实验内容
1、实验前准备工作
阅读参考资料,掌握操作系统内存管理的过程,并熟悉FF,BF,WF内存分配策略以及内存回收策略。
2、实验内容
根据下发ppt内容,内存分配与回收程序要求完成如下功能,具体详细设计要求见ppt。
1 -Set memory size (default=1024)//设置内存大小
2 - Select memory allocation algorithm//选择内存分配算法FF、BF、WF
3 - New process//创建新进程,分配内存
4 - Terminate a process//终止进程,回收内存
5 - Display memory usage//显示内存当前使用情况
0 – Exit//程序退出
三.方案设计
1.功能模块图及解释
2.核心数据结构及解释
struct free_block_type //空闲块
{
int size;
int start_addr;
struct free_block_type *next;
};
struct allocated_block //已分配的内存块
{
int pid;
int size;
int start_addr;
char process_name[PROCESS_NAME_LEN];
struct allocated_block *next;
};
1.Set memory size (default=1024):这个模块是用来设置内存大小的,从
键盘获取一个数字,并将它赋值给内存大小;若没有设置,则默认
内存的大小为1024。
2.Set_algorithm:这个模块是用来设置分配算法的,共有三种算法:首
次循环适配算法、最好适配算法、最差适配算法。从键盘输入一种
算法前的序号,根据算法点用不同的函数对内存进行分配;
3.New_process:此模块是用来创建进程的。从键盘输入进程号,调用
fork()创建进程并为其分配一定大小的内存,若分配成功,则将
其连接到已分配链表中,否则分配失败;
4.Kill_process:此模块是用来杀死进程的。从键盘输入一个进程号,先
调用find_process()函数进行查找,若找到,则调用kill()函数
将其杀死并释放内存空间。
5.Display_mem_usage:此模块是用来显示内存的使用情况的。将每个进
程的内存使用情况显示出来,包括起始地址和内存大小;
6.Do_exit:这个模块是用来结束程序的,直接调用exit()实现。
3.主要算法流程图及解释
算法调用图
四.测试数据及运行结果
1.正常测试数据(3组)及运行结果;
2.非正常测试数据(2组)及运行结果。
五.总结
1.实验过程中遇到的问题及解决办法;
实验过程中不会实现最佳适应算法,然后通过网上查阅别人的算法,自己研究,解决了这个问题。
2.对设计及调试过程的心得体会。
这次实验让我充分了解了内存管理的机制,进一步加深了对计算机的了解,对于以后系统的研究学习计算机起到了至关重要的作用。
六.附录:源代码(电子版)
#include
#include
#include
/*常量定义*/
#define PROCESS_NAME_LEN 32 /*进程名长度*/
#define MIN_SLICE 10 /*最小碎片的大小*/
#define DEFAULT_MEM_SIZE 1024 /*内存大小*/
#define DEFAULT_MEM_START 0 /*起始位置*/
/* 内存分配算法 */
#define MA_FF 1
#define MA_BF 2
#define MA_WF 3
/*描述每一个空闲块的数据结构*/
struct free_block_type{
int size;
int start_addr;
struct free_block_type *next;
};
/*每个进程分配到的内存块的描述*/
struct allocated_block{
int pid;
int size;
int start_addr;
char process_name[PROCESS_NAME_LEN];
struct allocated_block *next;
};
/*指向内存中空闲块链表的首指针*/
struct free_block_type *free_block;
/*进程分配内存块链表的首指针*/
struct allocated_block *allocated_block_head = NULL;
int mem_size=DEFAULT_MEM_SIZE; /*内存大小*/
int ma_algorithm = MA_FF; /*当前分配算法*/
static int pid = 0; /*初始pid*/
int flag = 0; /*设置内存大小标志,防止重复设置*/ void display_menu();
void do_exit();
struct free_block_type *init_free_block(int mem_size);
void set_mem_size();
void set_algorithm();
void new_process();
void kill_process();
void display_mem_usage();
void rearrange(int choice);
void abc();
void rearrage_BF();
void rearrage_WF();
main(){
char choice;
pid=0;
free_block = init_free_block(mem_size); //初始化空闲区display_menu();
while(1) {
printf("Please choice: ");
fflush(stdin);
choice=getchar(); //获取用户输入
switch(choice) {
case '1':
set_mem_size(); //设置内存大小break;
case '2':
set_algorithm();//设置算法flag=1;break;
case '3':
new_process();//创建新进程flag=1; break;
case '4':
kill_process();//删除进程flag=1; break;
case '5':
display_mem_usage();//显示内存使用flag=1; break;
case '0':do_exit();//释放链表并退出exit(0);
default: break;
}
choice=getchar();
}
}
//紧缩处理
void free_memory_rearrage(int memory_reduce_size,int allocated_size) {
struct free_block_type *p1,*p2;
struct allocated_block *a1,*a2;
if(memory_reduce_size!=0) //分配完还有小块空间
{
p1=free_block;
p2=p1->next;
p1->start_addr=0;
p1->size=memory_reduce_size;
p1->next=NULL;
mem_size=memory_reduce_size; //
}
else
{
p2=free_block;
free_block=NULL;
mem_size=0;
}
while(p2!=NULL)//释放节点
{
p1=p2;
p2=p2->next;
free(p1);
}
//allocated_block 重新修改链接
a1=(struct allocated_block *)malloc(sizeof(struct allocated_block));
a1->pid=pid;
a1->size=allocated_size;
a1->start_addr=memory_reduce_size; //已申请的开始地址,从memory_reduce_size开始
sprintf(a1->process_name, "PROCESS-%02d", pid);
a1->next=allocated_block_head;
a2=allocated_block_head;
allocated_block_head=a1;
while(a2!=NULL)
{
a2->start_addr=a1->start_addr+a1->size;
a1=a2;
a2=a2->next;
}
}
int allocate_mem(struct allocated_block *ab)
{
struct free_block_type *fbt, *pre;
int request_size=ab->size;
//int memory_count;//计算剩余分区总内存大小
fbt = pre = free_block;
while((pre!=NULL)&&(request_size>pre->size))//遍历查找匹配空白区{
//memory_count+=pre->size;
fbt=pre;
pre=pre->next;
}
if(!pre) //pre=pre->next结尾
{
if(mem_size>=request_size)/*memory_count*/
{
if(mem_size>=request_size+MIN_SLICE)
free_memory_rearrage(mem_size-request_size,request_size); //采用紧缩技术
else
free_memory_rearrage(0,mem_size); //采用紧缩技术,空间全部分配
return 0;//全部重定位,不返回上级
}
else
return -1;//分配失败!
}
else //内存能满足 request_size<=pre->size
{
if((pre->size-request_size)>MIN_SLICE)//找到可满足空闲分区且分配后剩余空间足够大,则分割
{
pre->size=pre->size-request_size;
ab->start_addr=pre->start_addr+pre->size;
}
else//找到可满足空闲分区且但分配后剩余空间比较小,则一起分配,删除该节点
{
if(pre==fbt)
{
fbt=pre->next;
free_block=fbt;
}
else
fbt->next=pre->next;
ab->start_addr=pre->start_addr;
ab->size=pre->size;
free(pre);//释放节点
}
}
mem_size-=ab->size;//...
rearrange(ma_algorithm);//分配成功,按照相应算法排序
return 1;
}
void new_process()
{
struct allocated_block *ab;
int size;
int ret;/*ret==1表示从空闲分区分配空间成功*/
if(mem_size==0)
{
printf("内存全部分配!无法创建新进程,请先释放其他进程!\n");
return;
}
ab=(struct allocated_block *)malloc(sizeof(struct allocated_block));
if(ab==NULL)
{
printf("No Mem!\n");
exit(1);
}
ab->next=NULL;
pid++;
sprintf(ab->process_name,"PROCESS-%02d",pid);//字符串格式化
ab->pid=pid;
while(1)
{
printf("Please input the memory for %s(0-%d):",ab->process_name,mem_size);
scanf("%d",&size);
if(size<=mem_size&&size>0)
{
ab->size=size;
break;
}
printf("Please input again!\n");
}
ret=allocate_mem(ab);//从空闲内存分配空间
/*如果此时allocated_block_head尚未赋值,则赋值*/
if((ret==1) &&(allocated_block_head == NULL))
allocated_block_head=ab;
else if(ret==1) /*分配成功,将该已分配块的描述插入已分配链表(头插<无头节点>)*/
{
ab->next=allocated_block_head;
allocated_block_head=ab;
}
else if(ret==-1)/*分配不成功*/
{
printf("Allocation fail\n");
free(ab);
return;
}
printf("Allocation Success!\n");
}
struct allocated_block *find_process(int pid)
{
struct allocated_block *p;
p=allocated_block_head;
while(p)
{
if(p->pid==pid)
return p;
p=p->next;
}
return p;
}
/*释放ab所表示的分配区*/
int free_mem(struct allocated_block *ab)
{
int algorithm = ma_algorithm;
struct free_block_type *fbt,*pre,*work;
mem_size+=ab->size;
fbt=(struct free_block_type *)malloc(sizeof(struct free_block_type));
if(!fbt)
return -1;
fbt->size = ab->size;
fbt->start_addr=ab->start_addr;
fbt->next=NULL;
rearrange(MA_FF);
pre=NULL;
work=free_block;
//查找插入位置
while((work!=NULL)&&(fbt->start_addr>work->start_addr))
{
pre=work;
work=work->next;
}
if(!pre)//插入开始位置
{
if (!work)
{
free_block=fbt; //
}else
{
fbt->next=work;
free_block=fbt;
if(fbt->start_addr+fbt->size==work->start_addr)//2)
{
fbt->next=work->next;
fbt->size=fbt->size+work->size;
free(work);
}
}
}
else
{
if(!work)
{
pre->next=fbt;
if(fbt->start_addr==pre->start_addr+pre->size)//1)
{
pre->next=work;
pre->size=fbt->size+pre->size;
free(fbt);
}
}
else
{
fbt->next=work;
pre->next=fbt;
// 检查并合并相邻的空闲分区
if((fbt->start_addr==
pre->start_addr+pre->size)&&(fbt->start_addr+fbt->size == work->start_addr))//3)
{
pre->next=work->next;
pre->size=pre->size+fbt->size+work->size;
free(fbt);
free(work);
}
else if(fbt->start_addr== pre->start_addr+pre->size)//1)
{
pre->next=work;
pre->size=pre->size+fbt->size;
free(fbt);
}
else if(work->start_addr==fbt->start_addr+fbt->size)//2
{
fbt->next=work->next;
fbt->size=work->size+fbt->size;
free(work);
}
}
}
// 将空闲链表重新按照当前算法排序
rearrange(ma_algorithm);
return 1;
}
/*释放ab数据结构节点*/
void dispose(struct allocated_block *free_ab)
{
struct allocated_block *pre,*ab;
if(free_ab==allocated_block_head)/*如果要释放第一个节点*/
{
allocated_block_head=free_ab->next;
free(free_ab);
return ;
}
pre=allocated_block_head;
ab=allocated_block_head->next;
while(ab!=free_ab)
{
pre=ab;
ab=ab->next;
}
pre->next=ab->next;
free(ab);
}
void kill_process()
{
struct allocated_block *ab;
int pid;
printf("Kill process,input pid = ");
scanf("%d",&pid);
ab=find_process(pid);
if(ab!=NULL)
{
free_mem(ab);/*释放ab所表示的分配区*/
dispose(ab);/*释放ab数据结构节点*/
printf("Kill Process Success!\n");
return;
}
printf("Kill Process Failure!\n");
}
/* 显示当前内存的使用情况,包括空闲区的情况和已经分配的情况 */
void display_mem_usage()
{
struct free_block_type *fbt=free_block;
struct allocated_block *ab=allocated_block_head;
/* 显示空闲区 */
printf("----------------------------------------------------------\n");
if(fbt==NULL)
printf("内存全部分配!\n");
else
{
printf("Free Memory:\n");
printf("%20s %20s\n", "\tstart_addr", " size");
while(fbt!=NULL)
{
printf("%20d %20d\n", fbt->start_addr, fbt->size);
fbt=fbt->next;
}
}
printf("----------------------------------------------------------\n");
/* 显示已分配区 */
if(ab==NULL)
printf("尚未开始分配!\n");
else
{
printf("\nUsed Memory:\n");
printf("%10s %20s %10s %10s\n", "\tPID", " ProcessName", " start_addr ", "size");
while(ab!=NULL)
{
printf("%10d %20s %10d %10d\n", ab->pid, ab->process_name, ab->start_addr, ab->size);
ab=ab->next;
}
}
printf("---------------------------------------------------------
-\n");
}
/*按BF算法重新整理内存空闲块链表*/
void rearrage_BF()
{
struct free_block_type *p,*p1,*p2;
struct free_block_type *last_flag;
p1=(struct free_block_type *)malloc(sizeof(struct free_block_type));
p1->next=free_block;
free_block=p1;//不改变p1,free_block指向头p1
if(free_block!=NULL)
{
for (last_flag=NULL; last_flag!=free_block; last_flag=p)
{
for (p=p1=free_block; p1->next!=NULL&&p1->next->next!=NULL&&p1->next->next!=last_flag;
p1=p1->next)
{
if (p1->next->size > p1->next->next->size)
{
p2 = p1->next->next;
p1->next->next = p2->next; //
p2->next = p1->next;
p1->next = p2;
p = p1->next->next;
}
}
}
}
p1 = free_block;
free_block = free_block->next;
free(p1);
p1 = NULL;
}
/*按WF算法重新整理内存空闲块链表*/
void rearrage_WF()
{
struct free_block_type *p,*p1,*p2;
struct free_block_type *last_flag;
p1=(struct free_block_type *)malloc(sizeof(struct free_block_type));
p1->next=free_block;
free_block=p1;//不改变p1,free_block指向头p1
if(free_block!=NULL){
for (last_flag=NULL; last_flag!=free_block; last_flag=p) {
for (p=p1=free_block; p1->next!=NULL&&p1->next->next!=NULL&&p1->next->next!=last_flag;
p1=p1->next)
{
if (p1->next->size < p1->next->next->size)
{
p2 = p1->next->next;
p1->next->next = p2->next; //
p2->next = p1->next;
p1->next = p2;
p = p1->next->next;
}
}
}
}
p1 = free_block;
free_block = free_block->next;
free(p1);
p1 = NULL;
}
void swap(int *p ,int *q)
{
int t;
t=*p;
*p=*q;
*q=t;
}
void rearrage_FF(){
struct free_block_type *tmp, *work;
printf("Rearrange free blocks for FF \n");
tmp = free_block;
while(tmp!=NULL)
{ work = tmp->next;
while(work!=NULL){
if( work->start_addr < tmp->start_addr) { /*地址递增*/
swap(&work->start_addr, &tmp->start_addr);
swap(&work->size, &tmp->size);
}
else work=work->next;
}
tmp=tmp->next;
}
}
void abc1()
{
struct free_block_type *p,*p1,*p2;
struct free_block_type *last_flag;
p1=(struct free_block_type *)malloc(sizeof(struct free_block_type));
p1->next=free_block;
free_block=p1;//不改变p1,free_block指向头p1
if(free_block!=NULL){
for (last_flag=NULL; last_flag!=free_block; last_flag=p)
{
for (p=p1=free_block;p1->next!=NULL&&p1->next->next!=NULL &&p1->next->next!=last_flag; p1=p1->next)
{
if (p1->next->start_addr > p1->next->next->start_addr)
{
p2 = p1->next->next;
p1->next->next = p2->next;
p2->next = p1->next;
p1->next = p2;
p = p1->next->next;
}
课程设计 题目:主存空间的分配与回收 学生姓名: 学院:信息工程学院 系别:计算机系 专业:计算机科学与技术 班级:计算机 指导教师:副教授 副教授 2011年月日 内蒙古工业大学课程设计任务书(三) 学院(系):信息学院计算机系课程名称:操作系统课程设计指导教师(签名):专业班级:计算机09-2 学生姓名:学号:
目录 第一章背景研究 (1) 1.1课题简介 (1) 1.2 设计要求 (1) 1.3概念原理 (1) 1.4 环境说明和使用工具 (2) 第二章详细设计 (2) 2.1功能介绍 (2) 2.1.1分配函数发fenpei()的执行过程(最佳适应算法) (2) 2.1.2回收进程空间所占的函数free()的执行过程 (2) 2.2函数的规格说明 (3) 2.2.1打印分配表空闲表函数 print() (3) 2.2.2为进程分配空间函数 fenpei(char *c, struct node *p,struct node *f) (3) 2.2.3回收进程所占空间函数struct node * free(char *c, struct node *p,struct node *f) (3) 2.3 主要数据结构 (3) 2.4 流程图 (5) 第三章核心算法的实现 (6) 3.1 分配函数 (6) 3.2回收函数 (11) 第四章测试 (15) 4.1 预测试 (15) 4.2 实际运行结果(截图) (16) 第五章总结 (18) 参考文献 (25)
第一章背景研究 1.1课题简介 操作系统是当代计算机软件系统的核心,是计算机系统的基础和支撑,它管理和控制着计算机系统中的所有软、硬件资源,可以说操作系统是计算机系统的灵魂。操作系统课程是计算机专业学生必须学习和掌握的基础课程, 是计算机应用人员深入了解和使用计算机的必备知识, 是进行系统软件开发的理论基础,也是计算机科学与技术专业的一门理论性和实践性并重的核心主干课程。本课程的目的是使学生掌握现代计算机操作系统的基本原理、基本设计方法及实现技术,具有分析现行操作系统和设计、开发实际操作系统的基本能力。 通过本次课程设计熟悉主存空间的分配与回收,所谓分配,就是解决多道作业或多进程如何共享主存空间的问题。所谓回收,就是当作业运行完成时,将作业或进程所占用的主存空间归还给系统。采用可变式分区管理,使用最佳适应算法实现主存的分配与回收。深入研究此算法有助于我们全面的理解内存的分配原理,培养我们逻辑思维能力。 1.2 设计要求 设计多个作业或进程动态请求内存资源的模拟系统,使用最佳适应算法实现内存的分配与回收,实现可变式分区管理;设计相应的内存分配算法,定义相关数据结构,以及输出显示每次请求分配内存的结果和内存的已分配和未分配的状况。 1.3概念原理 可变式分区管理的原理:区域的大小及起始地址是可变的,根据程序装入时的大小动态地分配一个区域。保证每个区域之中刚好放一个程序。这样可以充分地利用存储空间,提高内存的使用效率。如果一个程序运行完毕,就要释放出它所占有的分区,使之变成空闲区。这样就会出现空闲区与占用区相互交错的情况。这样就需要P 表,F表来分别表示内存的占用区状态与空闲区的状态。
操作系统内存管理
操作系统内存管理 1. 内存管理方法 内存管理主要包括虚地址、地址变换、内存分配和回收、内存扩充、内存共享和保护等功能。 2. 连续分配存储管理方式 连续分配是指为一个用户程序分配连续的内存空间。连续分配有单一连续存储管理和分区式储管理两种方式。 2.1 单一连续存储管理 在这种管理方式中,内存被分为两个区域:系统区和用户区。应用程序装入到用户区,可使用用户区全部空间。其特点是,最简单,适用于单用户、单任务的操作系统。CP/M和 DOS 2.0以下就是采用此种方式。这种方式的最大优点就是易于管理。但也存在着一些问题和不足之处,例如对要求内
存空间少的程序,造成内存浪费;程序全部装入,使得很少使用的程序部分也占用—定数量的内存。 2.2 分区式存储管理 为了支持多道程序系统和分时系统,支持多个程序并发执行,引入了分区式存储管理。分区式存储管理是把内存分为一些大小相等或不等的分区,操作系统占用其中一个分区,其余的分区由应用程序使用,每个应用程序占用一个或几个分区。分区式存储管理虽然可以支持并发,但难以进行内存分区的共享。 分区式存储管理引人了两个新的问题:内碎片和外碎片。 内碎片是占用分区内未被利用的空间,外碎片是占用分区之间难以利用的空闲分区(通常是小空闲分区)。 为实现分区式存储管理,操作系统应维护的数据结构为分区表或分区链表。表中各表项一般包括每个分区的起始地址、大小及状态(是否已分配)。
分区式存储管理常采用的一项技术就是内存紧缩(compaction)。 2.2.1 固定分区(nxedpartitioning)。 固定式分区的特点是把内存划分为若干个固定大小的连续分区。分区大小可以相等:这种作法只适合于多个相同程序的并发执行(处理多个类型相同的对象)。分区大小也可以不等:有多个小分区、适量的中等分区以及少量的大分区。根据程序的大小,分配当前空闲的、适当大小的分区。 优点:易于实现,开销小。 缺点主要有两个:内碎片造成浪费;分区总数固定,限制了并发执行的程序数目。 2.2.2动态分区(dynamic partitioning)。 动态分区的特点是动态创建分区:在装入程序时按其初始要求分配,或在其执行过程中通过系统调用进行分配或改变分区大小。与固定分区相比较其优点是:没有内碎
计算机操作系统内存分配实验报告记录
————————————————————————————————作者:————————————————————————————————日期:
一、实验目的 熟悉主存的分配与回收。理解在不同的存储管理方式下,如何实现主存空间的分配与回收。掌握动态分区分配方式中的数据结构和分配算法及动态分区存储管理方式及其实现过程。 二、实验内容和要求 主存的分配和回收的实现是与主存储器的管理方式有关的。所谓分配,就是解决多道作业或多进程如何共享主存空间的问题。所谓回收,就是当作业运行完成时将作业或进程所占的主存空间归还给系统。 可变分区管理是指在处理作业过程中建立分区,使分区大小正好适合作业的需求,并且分区个数是可以调整的。当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入,作业等待。随着作业的装入、完成,主存空间被分成许多大大小小的分区,有的分区被作业占用,而有的分区是空闲的。 实验要求使用可变分区存储管理方式,分区分配中所用的数据结构采用空闲分区表和空闲分区链来进行,分区分配中所用的算法采用首次适应算法、最佳适应算法、最差适应算法三种算法来实现主存的分配与回收。同时,要求设计一个实用友好的用户界面,并显示分配与回收的过程。同时要求设计一个实用友好的用户界面,并显示分配与回收的过程。 三、实验主要仪器设备和材料 实验环境 硬件环境:PC或兼容机 软件环境:VC++ 6.0 四、实验原理及设计分析 某系统采用可变分区存储管理,在系统运行当然开始,假设初始状态下,可用的内存空间为640KB,存储器区被分为操作系统分区(40KB)和可给用户的空间区(600KB)。 (作业1 申请130KB、作业2 申请60KB、作业3 申请100KB 、作业2 释放 60KB 、作业4 申请 200KB、作业3释放100KB、作业1 释放130KB 、作业5申请140KB 、作业6申请60KB 、作业7申请50KB) 当作业1进入内存后,分给作业1(130KB),随着作业1、2、3的进入,分别分配60KB、100KB,经过一段时间的运行后,作业2运行完毕,释放所占内存。此时,作业4进入系统,要求分配200KB内存。作业3、1运行完毕,释放所占内存。此时又有作业5申请140KB,作业6申请60KB,作业7申请50KB。为它们进行主存分配和回收。 1、采用可变分区存储管理,使用空闲分区链实现主存分配和回收。 空闲分区链:使用链指针把所有的空闲分区链成一条链,为了实现对空闲分区的分配和链接,在每个分区的起始部分设置状态位、分区的大小和链接各个分区的前向指针,由状态位指示该分区是否分配出去了;同时,在分区尾部还设置有一后向指针,用来链接后面的分区;分区中间部分是用来存放作业的空闲内存空间,当该分区分配出去后,状态位就由“0”置为“1”。 设置一个内存空闲分区链,内存空间分区通过空闲分区链来管理,在进行内存分配时,系统优先使用空闲低端的空间。 设计一个空闲分区说明链,设计一个某时刻主存空间占用情况表,作为主存当前使用基础。初始化空间区和已分配区说明链的值,设计作业申请队列以及作业完成后释放顺序,实现主存的分配和回收。要求每次分配和回收后显示出空闲内存分区链的情况。把空闲区说明
西安邮电大学 (计算机学院) 课内实验报告 实验名称:内存管理 专业名称:软件工程 班级: 学生姓名: 学号(8位): 指导教师: 实验日期:
实验五:进程 1.实验目的 通过深入理解区管理的三种算法,定义相应的数据结构,编写具体代码。充分模拟三种算法的实现过程,并通过对比,分析三种算法的优劣。 (1)掌握内存分配FF,BF,WF策略及实现的思路; (2)掌握内存回收过程及实现思路; (3)参考给出的代码思路,实现内存的申请、释放的管理程序,调试运行,总结程序设计中出现的问题并找出原因,写出实验报告。 2.实验要求: 1)掌握内存分配FF,BF,WF策略及实现的思路; 2)掌握内存回收过程及实现思路; 3)参考本程序思路,实现内存的申请、释放的管理程序,调试运行,总结程序设计中出现的问题并找出原因,写出实验报告。 3.实验过程: 创建进程:
删除其中几个进程:(默认以ff首次适应算法方式排列) Bf最佳适应算法排列方式:
wf最差匹配算法排列方式: 4.实验心得: 这次实验实验时间比较长,而且实验指导书中对内存的管理讲的很详细,老师上课的时候也有讲的很详细,但是代码比较长,刚开始的时候也是不太懂,但是后面经过和同学一起商讨,明白几种算法的含义: ①首次适应算法。在采用空闲分区链作为数据结构时,该算法要求空闲分区链表以地址递增的次序链接。在进行内存分配时,从链首开始顺序查找,直至找到一个能满足进程大小要求的空闲分区为止。然后,再按照进程请求内存的大小,从该分区中划出一块内存空间分配给请求进程,余下的空闲分区仍留在空闲链中。 ②循环首次适应算法。该算法是由首次适应算法演变而形成的,在为进程分配内存空间时,从上次找到的空闲分区的下一个空闲分区开始查找,直至找到第一个能满足要求的空闲分区,并从中划出一块与请求的大小相等的内存空间分配给进程。 ③最佳适应算法将空闲分区链表按分区大小由小到大排序,在链表中查找第一个满足要求的分区。 ④最差匹配算法将空闲分区链表按分区大小由大到小排序,在链表中找到第一个满足要求的空闲分区。 实验中没有用到循环首次适应算法,但是对其他三种的描述还是很详细,总的来说,从实验中还是学到了很多。 5.程序源代码: #include
精心整理西安邮电大学 (计算机学院) 课内实验报告 1. (1 (2 (3 原因,写出实验报告。 2.实验要求: 1)掌握内存分配FF,BF,WF策略及实现的思路; 2)掌握内存回收过程及实现思路; 3)参考本程序思路,实现内存的申请、释放的管理程序,调试运行,总结程序设计中出现的问题并找出原因,写出实验报告。
3.实验过程: 创建进程: 删除其中几个进程:(默认以ff首次适应算法方式排列) Bf最佳适应算法排列方式: wf最差匹配算法排列方式: 4.实验心得: 明 实验中没有用到循环首次适应算法,但是对其他三种的描述还是很详细,总的来说,从实验中还是学到了很多。 5.程序源代码: #include
#define PROCESS_NAME_LEN 32 //进程名长度 #define MIN_SLICE 10 //最小碎片的大小#define DEFAULT_MEM_SIZE 1024 //内存大小 #define DEFAULT_MEM_START 0 //起始位置 /*内存分配算法*/ #define MA_FF 1 #define MA_BF 2 #define MA_WF 3 /*描述每一个空闲块的数据结构*/ struct free_block_type { }; /* /* { }; /* /* void display_menu(); int set_mem_size(); void set_algorithm(); void rearrange(int algorithm); int rearrange_WF(); int rearrange_BF(); int rearrange_FF(); int new_process(); int allocate_mem(struct allocated_block *ab);
操作系统实验 内存的分配与回收 实验报告 一、实验题目:内存的分配与回收 二、实验内容:利用可变分区的首次适应算法,模拟内存的分配与回收。 三、实验目的:掌握可变分区首次适应算法的原理以及其编程实现。 四、实验过程: 1、基本思想:可变分区分配是根据进程的实际需求,动态地为之分配内存空间。首次适应算法要求空闲空间链以地址递增的次序链接。进行内存分配时,从链表头部开始依次检索,找到第一个不小于请求空间大小的空闲空间进行分配。分配时需考虑碎片问题,若分配会导致碎片产生则将整块分区分配。内存的回收需要考虑四种情况:⑴回收分区前后两个分区都空闲,则需要和前后两个分区合并;(2)回收分区只有前一分区空闲,则与前一分区合并;(3)回收分区只有后一分区空闲,则和后一分区合并;(4)回收分区独立,不考虑合并 。 2、主要数据结构: struct FreeArea{ 链结点包含的数据:分区号、大小、起址、标记 i nt ID; i nt size;
l ong address; i nt sign; }; struct Node { 双链表结点结构体:数据区、前向指针、后继指针 F reeArea data; s truct Node *prior; s truct Node *next; }*DLinkList; 3、输入、输出: 输入: I.内存分配时由键盘输入分区ID和大小; II.内存回收时由键盘输入需要回收的分区ID; 输出:输出内存的分配情况(按照地址从低到高) 4、程序流程图:
5、实验结果截屏:
6、源程序代码: #include
一.实验目的 通过编写和调试存储管理的模拟程序以加深对存储管理方 案的理解,熟悉可变分区存储管理的内存分配和回收。 二.实验内容 1.确定内存空间分配表; 2.采用最优适应算法完成内存空间的分配和回收; 3.编写主函数对所做工作进行测试。 三.实验背景材料 实现可变分区的分配和回收,主要考虑的问题有三个:第一,设计记录内存使用情况的数据表格,用来记录空闲区和作业占用的区域;第二,在设计的数据表格基础上设计内存分配算法;第三,在设计的数据表格基础上设计内存回收算法。 首先,考虑第一个问题,设计记录内存使用情况的数据表格,用来记录空间区和作业占用的区域。 由于可变分区的大小是由作业需求量决定的,故分区的长度是预先不固定的,且分区的个数也随内存分配和回收变动。总之,所有分区情况随时可能发生变化,数据表格的设计必须和这个特点相适应。由于分区长度不同,因此设计的表格应该包括分区在内存中的起始地址和长度。由于分配时空闲区有时会变成两个分区:空闲区和已分分区,回收内存分区时,可能会合并空闲分区,这样如果整个内存采用一张表格记录己分分区和空闲区,就会使表格操作繁琐。分配内存时查找空闲区进行分配,然后填写己分
配区表,主要操作在空闲区;某个作业执行完后,将该分区变成空闲区,并将其与相邻的空闲区合并,主要操作也在空闲区。由此可见,内存的分配和回收主要是对空闲区的操作。这样为了便于对内存空间的分配和回收,就建立两张分区表记录内存使用情况,一张表格记录作业占用分区的“己分分区表”;一张是记录空闲区的“空闲区表”。这两张表的实现方法一般有两种:一种是链表形式,一种是顺序表形式。在实验中,采用顺序表形式,用数组模拟。由于顺序表的长度必须提前固定,所以无论是“已分分区表”还是“空闲区表”都必须事先确定长度。它们的长度必须是系统可能的最大项数。 “已分分区表”的结构定义 #definen10//假定系统允许的最大作业数量为n struct {floataddress;//已分分区起始地址 floatlength;//已分分区长度、单位为字节 intflag;//已分分区表登记栏标志,“0”表示空栏目,实验中只支持一个字符的作业名 }used_table[n];//已分分区表 “空闲区表”的结构定义 #definem10//假定系统允许的空闲区最大为m struct {floataddress;//空闲区起始地址
学生学号 实验课成绩 武汉理工大学 学生实验报告书 实验课程名称 计算机操作系统 开 课 学 院 计算机科学与技术学院 指导老师姓名 学 生 姓 名 学生专业班级 2016 — 2017 学年第一学期
实验三 内存管理 一、设计目的、功能与要求 1、实验目的 掌握内存管理的相关内容,对内存的分配和回收有深入的理解。 2、实现功能 模拟实现内存管理机制 3、具体要求 任选一种计算机高级语言编程实现 选择一种内存管理方案:动态分区式、请求页式、段式、段页式等 能够输入给定的内存大小,进程的个数,每个进程所需内存空间的大小等 能够选择分配、回收操作 内购显示进程在内存的储存地址、大小等 显示每次完成内存分配或回收后内存空间的使用情况 二、问题描述 所谓分区,是把内存分为一些大小相等或不等的分区,除操作系统占用一个分区外,其余分区用来存放进程的程序和数据。本次实验中才用动态分区法,也就是在作业的处理过程中划分内存的区域,根据需要确定大小。 动态分区的分配算法:首先从可用表/自由链中找到一个足以容纳该作业的可用空白区,如果这个空白区比需求大,则将它分为两个部分,一部分成为已分配区,剩下部分仍为空白区。最后修改可用表或自由链,并回送一个所分配区的序号或该分区的起始地址。 最先适应法:按分区的起始地址的递增次序,从头查找,找到符合要求的第一个分区。
最佳适应法:按照分区大小的递增次序,查找,找到符合要求的第一个分区。 最坏适应法:按分区大小的递减次序,从头查找,找到符合要求的第一个分区。 三、数据结构及功能设计 1、数据结构 定义空闲分区结构体,用来保存内存中空闲分区的情况。其中size属性表示空闲分区的大小,start_addr表示空闲分区首地址,next指针指向下一个空闲分区。 //空闲分区 typedef struct Free_Block { int size; int start_addr; struct Free_Block *next; } Free_Block; Free_Block *free_block; 定义已分配的内存空间的结构体,用来保存已经被进程占用了内存空间的情况。其中pid作为该被分配分区的编号,用于在释放该内存空间时便于查找。size表示分区的大小,start_addr表示分区的起始地址,process_name存放进程名称,next指针指向下一个分区。 //已分配分区的结构体 typedef struct Allocate_Block { int pid; int size; int start_addr; char process_name[PROCESS_NAME_LEN]; struct Allocate_Block *next; } Allocate_Block; 2、模块说明 2.1 初始化模块 对内存空间进行初始化,初始情况内存空间为空,但是要设置内存的最大容量,该内存空间的首地址,以便之后新建进程的过程中使用。当空闲分区初始化
实验四存分配算法 1.实验目的 一个好的计算机系统不仅要有一个足够容量的、存取速度高的、稳定可靠的主存储器,而且要能合理地分配和使用这些存储空间。当用户提出申请主存储器空间时,存储管理必须根据申请者的要求,按一定的策略分析主存空间的使用情况,找出足够的空闲区域分配给申请者。当作业撤离或主动归还主存资源时,则存储管理要收回作业占用的主存空间或归还部分主存空间。主存的分配和回收的实现是与主存储器的管理方式有关的,通过本实验帮助学生理解在动态分区管理方式下应怎样实现主存空间的分配和回收。 背景知识: 可变分区方式是按作业需要的主存空间大小来分割分区的。当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入。随着作业的装入、撤离、主存空间被分成许多个分区,有的分区被作业占用,而有的分区是空闲的。 2.实验容 采用首次适应算法或循环首次算法或最佳适应算法分配主存空间。 由于本实验是模拟主存的分配,所以当把主存区分配给作业后并不实际启动装入程序装入作业,而用输出“分配情况”来代替。(即输出当时的空闲区说明表及其存分配表) 利用VC++6.0实现上述程序设计和调试操作。 3.实验代码 #include using namespace std; //定义存的大小 const int SIZE=64; //作业结构体,保存作业信息 struct Project{ int number; int length; }; //存块结构体,保存存块信息 struct Block{
主存空间的分配与回收实验报告
实验报告 课程名称:操作系统 实验名称:主存空间的分配与回收学号: 110310014 学生姓名:于钊 班级:信管1101班 指导教师:吴联世 实验日期: 2013 年12月5日
3、采用最先适应算法(顺序分配算法)分配主存空间。 按照作业的需要量,查空闲区说明表,顺序查看登记栏,找到第一个能满足要求的空闲区。当空闲区大于需要量时,一部分用来装入作业,另一部分仍为空闲区登记在空闲区说明表中。 由于本实验是模拟主存的分配,所以把主存区分配给作业后并不实际启动装入程序装入作业,而用输出“分配情况”来代替。 4、当一个作业执行完成撤离时,作业所占的分区应该归还给系统,归还的分区如果与其它空闲区相邻,则应合成一个较大的空闲区,登记在空闲区说明表中。例如,在上述中列举的情况下,如果作业2撤离,归还所占主存区域时,应与上、下相邻的空闲区一起合成一个大的空闲区登记在空闲区说明表中。 2)程序结构(流程图) 首次适应分配模拟算法
主存回收算法 3)实现步骤 实现动态分区的分配与回收,主要考虑三个问题:第一,设计记录主存使用情况的数据表格,用来记录空闲区和作业占用的区域;第二,在设计的数据表格基础上设计主存分配算法;第三,在设计的数据表格基础上设计主存回收算法。 1.设计记录主存使用情况的数据表格 由于动态分区的大小是由作业需求量决定的,故分区的长度是预先不固定的,且分区的个数也随主存分配和回收变动。总之,所有分区情况随时可能发生变化,数据表格的设计必须和这个特点相适应。由于分区长度不同,因此设计的表格应该包括分区在主存中的起始地址和长度。由于分配时,空闲区有时会变成两个分区:空闲区和已分分区,回收主存分区时,可能会合并空闲区,这样如果整个主存采用一张表格记录已分分区和空闲区,就会使表格操作繁琐。主存分配时查找空闲区进行分配,然后填写已分配区表,主要操作在空闲区;某个作业执行完后,将该分区贬词空闲区,并将其与相邻的空闲区合并,主要操作也在空闲区。由此可见,主存的分配与回收主要时对空闲区的操作。这样为了便于对主存空间的分配与回收,就建立两张分区表记录主存的使用情况:“已分配区表”记录作业占用分区,“空闲区表”记录空闲区。 这两张表的实现方法一般由两种:链表形式、顺序表形式。在本实验中,采用顺序表形式,用数组模拟。由于顺序表的长度必须提前固定,所以无论是“已分配区表”还是“空闲区表”都必须事先确定长度。它们的长度必须是系统可能的最大项数,系统运行过程中才不会出错,因此在多数情况下,无论是“已分配表区”还是“空闲区表”都是空闲栏目。已分配区表中除了分区起始地址、长度
一、实验目的 熟悉主存的分配与回收。理解在不同的存储管理方式下.如何实现主存空间的分配与回收。掌握动态分区分配方式中的数据结构和分配算法及动态分区存储管理方式及其实现过程。 二、实验内容和要求 主存的分配和回收的实现是与主存储器的管理方式有关的。所谓分配.就是解决多道作业或多进程如何共享主存空间的问题。所谓回收.就是当作业运行完成时将作业或进程所占的主存空间归还给系统。 可变分区管理是指在处理作业过程中建立分区.使分区大小正好适合作业的需求.并且分区个数是可以调整的。当要装入一个作业时.根据作业需要的主存量查看是否有足够的空闲空间.若有.则按需要量分割一个分区分配给该作业;若无.则作业不能装入.作业等待。随着作业的装入、完成.主存空间被分成许多大大小小的分区.有的分区被作业占用.而有的分区是空闲的。 实验要求使用可变分区存储管理方式.分区分配中所用的数据结构采用空闲分区表和空闲分区链来进行.分区分配中所用的算法采用首次适应算法、最佳适应算法、最差适应算法三种算法来实现主存的分配与回收。同时.要求设计一个实用友好的用户界面.并显示分配与回收的过程。同时要求设计一个实用友好的用户界面,并显示分配与回收的过程。 三、实验主要仪器设备和材料 实验环境 硬件环境:PC或兼容机 软件环境:VC++ 6.0 四、实验原理及设计分析 某系统采用可变分区存储管理.在系统运行当然开始.假设初始状态下.可用的内存空间为640KB.存储器区被分为操作系统分区(40KB)和可给用户的空间区(600KB)。 (作业1 申请130KB、作业2 申请60KB、作业3 申请100KB 、作业2 释放 60KB 、作业4 申请 200KB、作业3释放100KB、作业1 释放130KB 、作业5申请140KB 、作业6申请60KB 、作业7申请50KB) 当作业1进入内存后.分给作业1(130KB).随着作业1、2、3的进入.分别分配60KB、100KB.经过一段时间的运行后.作业2运行完毕.释放所占内存。此时.作业4进入系统.要求分配200KB内存。作业3、1运行完毕.释放所占内存。此时又有作业5申请140KB.作业6申请60KB.作业7申请50KB。为它们进行主存分配和回收。 1、采用可变分区存储管理.使用空闲分区链实现主存分配和回收。 空闲分区链:使用链指针把所有的空闲分区链成一条链.为了实现对空闲分区的分配和链接.在每个分区的起始部分设置状态位、分区的大小和链接各个分区的前向指针.由状态位指示该分区是否分配出去了;同时.在分区尾部还设置有一后向指针.用来链接后面的分区;分区中间部分是用来存放作业的空闲内存空间.当该分区分配出去后.状态位就由“0”置为“1”。 设置一个内存空闲分区链.内存空间分区通过空闲分区链来管理.在进行内存分配时.系统优先使用空闲低端的空间。 设计一个空闲分区说明链.设计一个某时刻主存空间占用情况表.作为主存当前使用基础。初始化空间区和已分配区说明链的值.设计作业申请队列以及作业完成后释放顺序.实现主存的分配和回收。要求每次分配和回收后显示出空闲内存分区链的情况。把空闲区说明链的变化情况以及各作业的申请、释放情况显示打印出来。
一、单项选择题 二、CADCA CADCC CBDBC DDADB DCAD 1.联想存储器在计算机系统中是用于__C____的。 A.存储文件信息B.与主存交换信息 C.内存地址变换D.内存管理信息 2.作业在执行中发生了缺页中断,经操作系统处理后,应该执行的指令是___D___。 A.被中断的前一条B.被中断的后一条 C.作业的第一条D.被中断的指令 在请求分页存储管理中,当指令的执行所需要的内容不在内存中时,发生缺页中断,当缺页调入内存后,应执行被中断指令。另:缺页中断作为中断与其它中断一样要经历如保护CPU环境,分析中断原因,转入缺页中断处理程序进行处理,恢复CPU环境等几个步骤,但缺页中断又是一种特殊的中断,它与一般中断相比,有着明显的区别,主要表现在下面两个方面:(1)缺页中断是在指令执行期间产生和处理中断信号的。(2)一条指令的执行期间,可能产生多次缺页中断。 3.实现虚拟存储器的目的是__D____。 A.实现存储保护B.实现程序浮动 C.扩充外存容量D.扩充内存容量 4.在段页式存储系统中,一个作业对应___C__。 A.多个段表B.一个段表,一个页表 C.一个段表,多个页表D.多个段表,多个页表 5.在虚拟页式存储管理方案中,完成将页面调入内存的工作的是___A___。 A.缺页中断处理B.页面淘汰过程C.工作集模型应用D.紧缩技术利用 6.采用分页式内存管理时,重定位的工作是由___C___完成的。 A.操作系统B.用户C.地址转换机构D.内存空间分配程序 7.在分页式内存管理系统中可能出现的问题是__B____。 A.颠簸B.不能共享C.外部碎片D.动态链接 8.在下列有关分页式内存管理的叙述中正确的是___D___。 A.程序和数据是在开始执行前一次性和装入的 B.产生缺页中断一定要淘汰一个页面 C.一个被淘汰的页面一定要写回外存 D.在页面中有“访问位”和“修改位”等消息 9. 在可变式分配方案中,最佳适应算法是将空白区在空白区表中按___C___次序排列。 A.地址递增B.地址递减C.容量递增D.容量递减 10. 在可变分区分配方案中,将空白分区按地址递增次序排列是要采用___C___。 A.最佳适应算法B.最差适应算法 C.首次适应算法D.最迟适应算法
操作系统实验 存的分配与回收 实验报告 一、实验题目:存的分配与回收 二、实验容:利用可变分区的首次适应算法,模拟存的分配与回收。 三、实验目的:掌握可变分区首次适应算法的原理以及其编程实现。 四、实验过程: 1、基本思想:可变分区分配是根据进程的实际需求,动态地为之分配存空间。首次适应算法要求空闲空间链以地址递增的次序。进行存分配时,从链表头部开始依次检索,找到第一个不小于请求空间大小的空闲空间进行分配。分配时需考虑碎片问题,若分配会导致碎片产生则将整块分区分配。存的回收需要考虑四种情况:⑴回收分区前后两个分区都空闲,则需要和前后两个分区合并;(2)回收分区只有前一分区空闲,则与前一分区合并;(3)回收分区只有后一分区空闲,则和后一分区合并;(4)回收分区独立,不考虑合并 。 2、主要数据结构: struct FreeArea{ 链结点包含的数据:分区号、大小、起址、标记 int ID; int size;
long address; int sign; }; struct Node { 双链表结点结构体:数据区、前向指针、后继指针FreeArea data; struct Node *prior; struct Node *next; }*DLinkList; 3、输入、输出: 输入: I.存分配时由键盘输入分区ID和大小; II.存回收时由键盘输入需要回收的分区ID; 输出:输出存的分配情况(按照地址从低到高) 4、程序流程图:
5、实验结果截屏:
6、源程序代码: #include
内存管理实验报告
信息科学与技术学院实验报告 课程名称: 实验项目: 实验地点:指导教师: 日期: 实验类型:(验证性实验综合性实验设计性实验) 专业: 计算机外包班级: 14外三姓名: 周鹏飞学号: 1414104033 一、实验目的及要求 通过此次实验,加深对内存管理的认识,进一步掌握内存的分配,回收算法的思想。 二、实验仪器、设备或软件 Windows操作系统PC一台;VC++6.0 三、实验内容及原理 原理:设计程序模拟内存的动态分区内存管理方法。内存空闲区使用空闲分区表进行管理,采用最先适应算法从空闲分区表中寻找空闲区进行分配,内存回收时不考虑与相邻空闲分区的合并。 假定系统的内存共640k,初始状态为操作系统本身占用40k.t1时刻,为作业A,B,C分配80k,60k,100k的内存空间;t2时刻作业B完成;t3时刻为作业D分配50k的内存空间;t4时刻作业C,A完成;t5时刻作业D完成。要求编程序分别输出t1,t2,t3,t4,t5时刻内存的空闲区的状态。 实验内容: #include
#define size 10 //不再切割剩余分区的大小 typedef struct PCB_type { char name;//进程名 int address;//进程所占分区首地址 int len;//进程所占分区的长度 int valid;//PCB标识符(有效,无效) }PCB; Typedef struct seqlist //进程信息队列 { PCB PCBelem[maxPCB];// maxPCB为为系统中允许的最多进程数 int total; //系统中实际的进程数 }PCBseql;//分区类型的描述 typedef struct Partition { int address;//分区起址 int len;//分区的长度 int valid;//有标识符(有效,无效) }Part;//内存空闲分区表(顺序表)描述 typedef struct Partlist //空白分区链 { Part Partelem[maxPart];//maxPart为系统中可能的最多空闲分区数 int sum;//系统中世纪的分区数 }Partseql;//全局变量 PCBseql *pcbl;//进程队列指针 Partseql *part1;//空闲队列指针 #intclude “MainManager.h” void initpcb() //初始化进程表vpcb1 { int i; pcb1->PCBelem[0].address=0; pcb1->PCBelem[0].len=0; pcb1->PCBelem[0].name=’s’; pcb1->PCBelem[0].valid=1; pcb1->total=0; for(i=1;i 内存的动态存储管理 一、实验内容 编写程序实现动态分区存储管理方式的主存分配与回收。具体内容包括:首先确定主存空间分配表;然后采用最先适应算法完成主存空间的分配与回收;最后编写主函数对所做工作进行测试 二、实验原理 模拟存储管理中内存空间的管理和分配内存空间的管理分为固定分区管理方式,可变分区管理方式,页式存储管理,段式存储管理。 题目:模拟内存分配与回收 三、实验步骤(或过程) 在Microsoft Visual C++ 6.0环境下运行 1.设计一个空闲分区表,空闲分区表通过空闲分区链表来管理,在进行内存分配时,系统优先使用空闲分区低端的空间。 2.设计一个内存分区表,可用链表管理,用以表示当前以内存使用情况。 3.设计一个进程申请队列以及进程完成后的释放顺序,实现主存的分配和回收。 4.要求每次分配和回收后把空闲分区的变化情况以及各进程的申请、释放情况以及各进程的申请、释放情况以图形方式显示、打印出来。 最佳适应算法: 该算法总是把满足要求、又是最小的空闲区分配给作业。检查空闲区说明表是否有满足作业要求的空闲区,也分为三种情况:大于,等于,小于。若检查到有“等于”的情况,就可以直接分配,若没有,则继续检查是否有“大于”的情况 代码实现如下: #include #include q->size=50; p->next=q; p=q; q=new memory; //空闲块3,大小30,起始地址75k q->begin=75; q->pro=0; q->size=30; p->next=q; p=q; q=new memory; //空闲块4,大小45,起始地址105k q->begin=105; q->pro=0; q->size=45; p->next=q; p=q; q=new memory; //空闲块5,大小54,起始地址150k q->begin=150; q->pro=0; q->size=54; p->next=q; p=q; q=new memory; //空闲块6,大小52,起始地址204k q->begin=204; q->pro=0; q->size=52; p->next=q; q->next=NULL; } else //动态内存,只有一个大的内存块 { p=new memory; //空闲块251k,起始地址是5k p->begin=5; p->pro=0; p->size=251; p->next=NULL; base->next=p; } } void assign(memory *q,char pro,int size) //动态,给进程pro在内存块q->next上分配size 大小,q不为空且q->next不为空操作系统原理-内存分配与回收
操作系统实验内存分配(链表实现)