动态多分区存储管理模拟系统

这篇博客详细介绍了操作系统课程设计中的动态多分区存储管理模拟系统的设计和实现。主要内容包括内存管理的理解,内存分配与回收算法的原理,以及通过编程实践掌握分区管理的方法。程序设计涉及内存分配和回收函数,使用链表数据结构记录主存使用情况,并实现了首次适应、最佳适应和最坏适应三种算法。调试过程中解决了数据读取、死循环和分区合并等问题。
摘要由CSDN通过智能技术生成

操作系统课程设计实验报告


设计题目三:动态多分区存储管理模拟系统

——


一、设计题目要求

   1、对理论课中学习的内存管理当中的概念做进一步的理解;

   2、了解内存管理任务的主要实现方法;

   3、掌握内存的分配,回收等主要算法的原理;

   4、通过编程,熟悉分区式存储管理方法中内存分配回收算法的实现方法。

二、程序设计思路及流程图

   程序功能简介:

    主存分配函数:寻找空闲分区,空闲分区表的修改,已分配分区表的修改。其中,若寻找到的最小适合空间相对作业请求的空间来说仍过大,则要分割该分区。

主存回收函数:回收作业释放的分区、修改已分配分区表、修改空闲分区表。其中,若回收的分区有上邻空闲分区或(和)下邻空闲分区的,要合并成为一个空闲分区,登记在空闲分区表的一个表项里。

程序设计思路:

(1)设计一个用来记录主存使用情况的数据结构,登记空闲区和作业区占用的情况;

(2)在设计好的该数据结构上面,再设计一个主存分配算法;

(3)在设计好的该数据结构上面,再设计一个主存回收算法。

开始时,纠结于使用什么数据结构来构建空闲分区表和一个分配表,很明显的是,链表比静态的数组更好一点。但是在思考链表的使用时,竟然错误地定义了两种类型的链表,其实没有必要的,因为这两个表的内容是相同的,一个类型就可以了。这我也是第一次在一个程序里面声明两个链表,对两个链表进行操作。

程序流程图:

见附录A

三、涉及的背景知识及所用函数简介

1、malloc函数

函数原型 :void *malloc(unsigned int num_bytes);

头文件 :stdlib.h

作用 :分配长度为num_bytes字节的内存块

返回值 :分配成功则返回指向被分配内存的指针,否则返回空指针NULL。

2、freopen函数

函数原型 :FILE *freopen(char *filename ,char *type,FILE *stream);

头文件 :stdio.h

作用 :替换一个流,或者说重新分配文件指针,实现重定向。

参数 :filename:要打开的文件名

stream:文件指针,通常使用标准流文件

返回值 :成功返回参数文件指针。

3、strcmp函数

函数原型 :extern int strcmp(const char *s1,const char *s2); 

头文件 :string.h

作用 :比较字符串s1和s2

参数 :s1:第一个字符串

s2:第二个字符串

返回值 :如果s1小于s2,返回负数;如果s1大于s2,返回正数;二者相等 返回0.

4、strcpy 函数

函数原型 :extern char strcpy(char dest,const char src); 

头文件 :string,h

作用 :把从src地址开始且含有NULL结束符的字符串复制到已dest开始 的地址空间

参数 :scr:原串

Dest:目标串

返回值 :目标串的地址

四、程序所用数据结构简介

int choose :选择要进行的操作;

#define total_size 128:磁盘的总大小;

 

typedef struct node

{

    char name[5];

    float address;

    float length;

    int flag;

    struct node *next;

}node, *pnode;

定义结点类型;

 

typedef struct 

{

    node *head;

}linklist, *plinklist;

定义链表类型;

linklist used_table, free_table;声明两条链表;

plinklist pused_table, pfree_table; 声明两个指向链表的指针;

 

void system_init(); 初始化系统,创建两条链表;

plinklist create_list_in_head();  创建链表;

void insert_node_address_asc(plinklist pl, pnode item);按地址升序在链表中插入结点;

void insert_node_length_asc(plinklist pl, pnode item);按空间大小升序在链表中插入结点;

void insert_node_length_desc(plinklist pl, pnode item);按空间大小降序在链表中插入结点;

void delete_node_in_list(plinklist pl, pnode item);从链表中删除结点;

void display_node_in_list(plinklist pl);显示链表中的所有结点;

void ff();调用首次适应算法ff;

void bf();调用最佳适应算法bf;

void wf();调用最坏适应算法为wf;

五、程序源代码

见附录B

六、调试方案及调试过程记录与分析

输入文件选取:

本程序共3个输入文件,每种算法分别对应一个txt测试数据,见附录B。

输入数据的处理:

采用重定向输入法freopen(“in.txt”, “r”, stdin);

即改变输入路径,不从键盘上输入,而是从文件中读取;

因此,在主函数中只能有一次选择使用哪种算法,若要再次选择其他算法,则需再次输入命令./main。

 

测试结果、调试过程:

第一次测试结果:文件数据读取错误,数据读取错位。

第一次调试:去掉while(1),重新执行,文件可以正常读取。

第二次测试结果:输出结果陷入死循环。

第二次调试:接受数据的elem变量在接收完一次数据之后没有做初始化处理。

第三次测试结果:结果可以正常输出,但wf算法,并未按空间大小降序排列。

第三次调试:在合并分区时,借用临时变量存储curr。

第四次测试结果:合并可以正常运行,经测试,三种算法均正常执行,结果也是正确的。

七、思考与体会

这次写代码时,没有备份,一不小心把代码全部用rm命令删除了,当时真是欲哭无泪,白辛苦了这么长时间,就这样被自己毁了,还好,用了一个上午重新写了一下,血的教训呀! 

要熟练掌握链表的操作,插入,删除。注意特殊情况的处理,比如prev为空时;遍历结束,curr为空时;链表中没有结点时,只有一个结点时,都要认真考虑。

合并的原则:即在物理空间上,地址连续的可以进行合并。

在bf,wf实现时,分区的合并处理,对elem的影

  • 6
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
模拟实现动态可变分区存储管理系统,内存资源的分配情况用一个单链表来表示,每一个节点表示一个可变分区,记录有内存首地址、大小、使用情况等,模拟内存分配动态输入构造空闲区表,键盘接收内存申请尺寸大小,根据申请,实施内存分配,并返回分配所得内存首址。分配完后,调整空闲区表,并显示调整后的空闲区表和已占用的区表。如果分配失败,返回分配失败信息。模拟内存回收。根据空闲区表,从键盘接收回收区域的内存作业代号。回收区域,调整空闲区表,并显示调整后的空闲区表。对于内存区间的分配,移出,合并就是相应的对链表节点信息进行修改,删除和创建相应的节点。 在模拟实现动态可变分区存储管理系统中用到的是“最佳适应算法”与“最坏适应算法”。所谓“最佳”是指每次为作业分配内存时,总是把满足要求、又是最小的空闲分区分配给作业,避免“大材小用”。因此保证每次找到的总是空闲分区中最小适应的,但这样会在储存器中留下许多难以利用的小的空闲区。最坏适应分配算法是要扫描整个空闲分区表或链表,总是挑选最大的一个空闲分区割给作业使用。进入系统时我们需要内存首地址和大小这些初始化数据。成功后我们可以自由的使用首次适应算法与最佳适应算法对内存进行分配。内存经过一系列分配与回收后,系统的内存分配情况不再连续。首次适应算法与最佳适应算法的差异也就很容易的体现在分配时。动态可变分区存储管理模拟系统采用最佳适应算法、最坏适应算法内存调度策略,对于采用不同调度算法,作业被分配到不同的内存区间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值