ImageVerifierCode 换一换
格式:DOCX , 页数:16 ,大小:116.41KB ,
资源ID:8948057      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/8948057.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(内存的申请和释放.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

内存的申请和释放.docx

1、内存的申请和释放计算机学院网络工程专业操作系统课程设计题目:内存的申请和释放班级:网工11102班姓名:郭阳学号: 2同组人姓名:起迄日期: 第一周,第二周课程设计地点: E3A513指导教师:贺玉才评阅意见:成绩评定:评阅人:日期:完成日期:2014年3月一、概述1、设计目的了解操作系统的内存分配的方法2、开发环境WINDOWS环境Visual C+6.0 二、设计要求 定义一个自由存储块链表,按块地址排序,表中记录块的大小。当请求分配内存时,扫描自由存储块链表,知道找到一个足够大的可供分配的内存块,若找到的块的大小正好等于所请求的大小时,就把这一块从自由链表中取下来,返回给申请者。若找到的

2、块太大,即对其分割,并从该块的高地址不分往低地址部分分割,取出大小合适的块返还给申请者,愈小的低地址部分留在链表中。若找不到足够大的块,就从操作系统中请求另外一个足够大的内存区域,并把它连接到自由块链表中,然后再继续搜索。 释放存储块也要搜索自由链表,目的是找到适当的位置将要释放的块插进去,如果被释放的块的任何一边与链表中的某一块临接,即对其进行合并操作,直到没有合并的临接块为止,这样可以防止存储空间变得零碎。三、实验基本原理分区存储管理是给内存中的进程划分适当大小的存储区,以连续存储各进程的程序和数据,使各进程能并发地执行。最优适应分配算法扫描整个未分配区表或链表,从空闲区中挑选一个能满足用

3、户进程要求的最小分区进行分配。 在可变分区模式下,在系统初启且用户作业尚未装入主存储器之前,整个用户区是一个大空闲分区,随着作业的装入和撤离,主存空间被分成许多分区,有的分区被占用,而有的分区时空闲的。为了方便主存空间的分配和去配,用于管理的数据结构可由两张表组成:“已分配区表”和“未分配区表”。在“未分配表中”将空闲区按长度递增顺序排列,当装入新作业时,从未分配区表中挑选一个能满足用户进程要求的最小分区进行分配。这时从已分配表中找出一个空栏目登记新作业的起始地址和占用长度,同时修改未分配区表中空闲区的长度和起始地址。当作业撤离时已分配区表中的相应状态变为“空”,而将收回的分区登记到未分配区表

4、中,若有相邻空闲区再将其连接后登记。可变分区的回收算法较为复杂,当一个作业撤离时,可分为4种情况:其临近都有作业(A和B),其一边有作业(A或B),其两边均为空闲区。尤其重要的是,在程序中利用“ new 类型T(初值列表)”申请分配用于存放T类型数据的内存空间,利用 “delete 指针名”释放指针所指向的内存空间。 四、程序流程图1、整体程序流程图2、内存分配allocate()流程图五、源程序1、数据结构(1)内存块struct space /定义内存空间结构体 long startaddress; long length; struct space *next;space *pbc; (

5、2)、作业块struct work /定义进程结构体 char name20; long startaddress; long length; struct work *next;work *S; 2、主要功能函数allocate() : 实现内存分配,并在当中调用display(pbc),以及display(S) 两个函数显示内存分配完后的空闲块链表和进程链表情况。requireback(): 实现内存回收,在满足情况的条件下调用allocate()对用户申请的内存块进行回收并在当中调用display(pbc),以及display(S)显示内存回收完后的空闲块链表和进程链表情况。 callb

6、ack(): 按内存回收时的四种情况对内存进行回收。display(pbc): 对空闲块链表中的空闲块进行从小到大排序并显示空闲链情况。display(S): 对进程链表中的进程进行从小到大排序并显示进程链情况。main(): 创建并初始化空闲块链表和进程链链表,用户选择操作功能3、源程序代码#include #include#include struct space /定义内存空间结构体 long startaddress; long length; struct space *next;space *pbc; /申明结构体指针struct work /定义进程结构体 char name20

7、; long startaddress; long length; struct work *next;work *S; /申明结构体指针void callback(work *r); /申明callback()函数原型void display(space *pbc); /申明display()函数原型void display(work *S); void allocate() /内存分配函数实现 work *q,*w; q=new work; /申请分配用于存放work类型的数据的内存空间 cout请输入进程名和占用空间大小:q-nameq-length; if(q-length=0) /判

8、断输入进程的合法性 cout进程错误.next!=NULL) /进程链不为空 if(strcmp(w-next-name, q-name)=0) /判断进程名是否已经存在 cout此进程名已经存在!next; if(w-next=NULL) /进程名不存在,继续进行内存分配 space *p,*r; p=pbc; r=p; while(p-next!=NULL&p-next-lengthlength) /在空间链中寻找第一个大于所输入的进程大小的空闲块 r=p; p=p-next; if(p-next=NULL) /空闲链中无大于所输入进程空间大小的空闲块 cout空间不足,分配失败!star

9、taddress=p-next-startaddress; /将该空闲块的起始地址赋给所输入的进程 q-next=S-next; S-next=q; /将所输入的进程插入work链首。 p-next-length-=q-length; if(p-next-length!=0) /该空闲块空间有剩余,改变该空闲块的起始地址 p-next-startaddress+=q-length; else /该空闲块空间无剩余 if(p-next-next!=NULL) /该空闲块不处于空闲链链尾 p-next=p-next-next; /删除该空闲块,修改空闲链 else r-next=NULL; /该空

10、闲块处于空闲链链尾,修改空闲链 delete p-next; /释放该空闲块的空间 display(pbc); /显示空闲链情况 display(S); /显示进程链情况 void requireback() /用户申请进程回收函数 char name20; coutname; work *p; p=S; while(p-next!=NULL) /进程链不为空 if(strcmp(p-next-name, name)=0) /寻找与用户要求回收的进程名相同的进程 callback(p); /调用进程回收函数,回收进程 return; p=p-next; if(p-next=NULL) cout

11、此进程不存在!next; space *p=NULL,*q=NULL; long n; n=w-length; if(pbc-next=NULL) /空闲链为空 space *f=new space; /申请分配用于存放space类型的数据的内存空间,并将首地址赋给指针f f-startaddress=0; /初始该空间首地址 f-length=n; /将所要回收的进程大小赋给该空间 f-next=NULL; pbc-next=f; /将该空间块插入空闲链中 t-next=w-next; delete w; /释放空间 cout回收完毕!next; while(p!=NULL&p-starta

12、ddressstartaddress) /在空闲链表中寻找插入新的空闲区的合适位置 q=p; p=p-next; if(q=NULL)&(w-startaddress+n=p-startaddress) p-startaddress-=n; /修改下邻起始地址 p-length+=n; /将该空闲块与下邻合并 t-next=w-next;/修改进程链,删除进程链中所要回收的进程 delete w; /释放空间 cout回收完毕!startaddress+n!=p-startaddress) /q为空,且该空间的结束地址不是下临的结束地址 space *sp=new space; /申请分配用于

13、存放space类型的数据的内存空间,并将首地址赋给指针sp sp-startaddress=w-startaddress; /将该空间的起始地址赋给sp sp-length=n; /将该空间的大小赋给sp sp-next=pbc-next; /将sp插入空闲链中 pbc-next=sp; t-next=w-next; /修改进程链,删除所回收的进程 delete w; cout回收完毕!startaddress+q-length=w-startaddress)&(w-startaddress+n=p-start address)/上下均空 q-next=p-next; /修改空闲链 q-len

14、gth=q-length+p-length+n; /将该空闲块与上下邻合并 t-next=w-next; /修改进程链,删除所回收的进程 delete w; /释放空间 else if(q!=NULL)&(w-startaddress+n=p-startaddress) /下邻空 p-startaddress-=n; /修改下邻起始地址 p-length+=n; /将该空闲快与下邻合并 t-next=w-next; delete w; else if(q!=NULL)&(q-startaddress+q-length=w-startaddress)/上邻为空 q-length+=n; /改变上

15、邻的大小,将两个空闲块合并 t-next=w-next; /修改进程链,删除所回收的进程 delete w; /释放空间 else /上下邻都不为空 space *sp=new space; /申请分配用于存放space类型的数据的内存空间,并将首地址赋给指针sp sp-startaddress=w-startaddress; /将所回收的进程首地址赋给sp sp-length=n; /将缩回收的进程大小赋给sp sp-next=pbc-next; pbc-next=sp; /将sp插入空闲链链首 t-next=w-next; /修改进程链,删除所回收的进程 delete w; /释放空间 c

16、out回收完毕!next; /空闲块从小到大排序 pbc-next=NULL; while(sa!=NULL) sd=pbc;sf=pbc-next; while(sf!=NULL)&(sf-lengthlength) sd=sf;sf=sf-next; sk=sa-next; if(sf=NULL) sd-next=sa;sa-next=NULL; else sa-next=sf;sd-next=sa; sa=sk; void display(space *pbc) /空闲链显示函数实现 space *p,*q,*r,*e; p=pbc-next; /空闲块从小到大排序 pbc-next=N

17、ULL; while(p!=NULL) r=pbc;q=pbc-next; while(q!=NULL)&(q-startaddressstartaddress) r=q;q=q-next; e=p-next; if(q=NULL) r-next=p;p-next=NULL; else p-next=q;r-next=p; p=e; space *t=pbc-next; coutendl可用空闲区:endl; if(t=NULL) cout无空闲区了.endl; return; while(t!=NULL) cout起始地址:startaddress长度:lengthnext; void di

18、splay(work *S) /进程链显示函数实现 work *p,*q,*r,*f; p=S-next; /进程链表排序 S-next=NULL; while(p!=NULL) r=S;q=S-next; while(q!=NULL)&(q-startaddressstartaddress) /按从小到大 r=q;q=q-next; f=p-next; if(q=NULL) r-next=p;p-next=NULL; else p-next=q;r-next=p; p=f; work *t=S-next; coutendl已分配进程:endl; if(t=NULL) cout内存中无进程.e

19、ndl; return; while(t!=NULL) cout进程名:name起始地址:startaddress长度:lengthnext; coutstartaddress=0; /初始化p的起始地址 p-length=130; /初始花p的大小 p-next=NULL; pbc-next=p; /将pbc作为p的头指针,创建空闲链 S=new work; /创建进程链头指针 S-next=NULL; int b; cout 最佳适应算法模拟内存分配与回收endl; coutendl; coutendl; cout功能选项: 0:分配内存 1:回收内存 2:退出endl; coutendl

20、; while(1) /循环选择功能 coutendlb; switch(b) case 0: allocate(); break; /功能0:进行内存分配 case 1: requireback(); break; /功能1: 进行内存回收 case 2: ;break; /功能2: 退出 六、运行结果1、测试用例与程序运行结果截图 程序运行结果:分配成功 程序运行结果:回收成功 七、总结在做课程设计的过程中我遇到了不少问题,比如链表指针部分就很容易搞混,而且很多地方不容易考虑全面,比如内存回收时空闲区的合并部分,要考虑释放的内存空间前后是否为空闲区,若是,如何来合并,如果释放的内存块是链表

21、的最后一个,或是链表的倒数第二个,则这两种情况要单独讨论,因为当内存空间释放后存在一个后向指针的定义问题,若是在链表中间,则可以直接指定,但若是在链表的末尾,则要指定为NULL,另外若用的是最佳适应算法,进行内存回收时还有考虑前后空闲块地址是否相接,因为它是按照块的大小排序的,若不相接,即使两个块在链表中的位置相邻,也不能合并,而且要注意每次分配或释放空间后都要对链表进行排序,这是由算法思想决定的,这些条件都是在做的过程中逐步完善的,所遇到的这些问题通过问老师、查阅资料得以解决。题目做完后,我对内存动态分区部分又有了更加深刻的理解,我个人的编程能力也得到了一定程度的提高,在课堂上我们只是听老师把理论知识给讲了一遍,课下很快就忘了,通过做课程设计,我们把它真正的实现出来,这样印象就更深了,而且不仅仅局限于理论层次,也提高了我们分析问题、解决问题的能力,希望以后我们可以有更多的机会来做这些东西。八、参考文献1、人民邮电出版社 宗大华操作系统教程2、清华大学出版社出版的 严蔚敏数据结构(c语言版)3.、清华大学出版社出版的 李爱华c+语言程序设计

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1