操作系统|C语言模拟实现首次适应和最佳适应两种内存分配算法以及内存回收
两种算法
首次适应
首次适应算法从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给作业,这种方法目的在于减少查找时间。为适应这种算法,空闲分区表(空闲区链)中的空闲分区要按地址由低到高进行排序。该算法优先使用低址部分空闲区,在低址空间造成许多小的空闲区,在高地址空间保留大的空闲区。
最佳适应
最佳适应算法是指从全部空闲区中找出能满足作业要求且大小最小的空闲分区的一种计算方法,这种方法能使碎片尽量小。
程序代码
#include <stdio.h>
#include <stdlib.h>
struct area
{
int id; // 编号
int addr_front; //首地址
int size; //分区大小
int flag; //分配标志
struct area *front; //上一分区
struct area *next; //下一分区
};
typedef struct area partion;
partion *head = NULL; //分区队列头节点
int need; //需求
int choice = 1; //操作选项
partion *createPartion(int id, int addr_front, int size, int flag); //生成一个节点
void inputNeed(); //输入需求量
void assign(partion *ptr, int need); //分配分区
void first_fit(); //首次适应算法
void best_fit(); //最佳适应算法
void showMemoryInfo(); //打印分区分配状况
void recovery(); //分区回收
void changeIdValue(partion *ptr, int delta); //改变从ptr开始所有节点的id值
int main(void)
{
head = createPartion(0, 0, 200, 0);
while (choice != 0)
{
puts("-------------------\nchoose operation:\n1:First_Fit;\n2:Best_Fit;\n3:recovery;\n4:showinformation;\n0:quit......\n-------------------");
scanf("%d", &choice);
switch (choice)
{
case 1:
inputNeed();
first_fit();
break;
case 2:
inputNeed();
best_fit();
break;
case 3:
recovery();
break;
case 4:
showMemoryInfo();
break;
case 0:
puts("byebye");
break;
default:
break;
}
}
system("pause");
return 0;
}
partion *createPartion(int id, int addr_front, int size, int flag)
{
partion *p = (partion *)malloc(sizeof(partion));
p->id = id;
p->addr_front = addr_front;
p->size = size;
p->flag = flag;
p->front = NULL;
p->next = NULL;
return p;
}
void inputNeed()
{
printf("please input the need:");
scanf("%d", &need);
}
void first_fit()
{
partion *fit = NULL;
partion *ptr = head;
while (ptr != NULL)
{
if (ptr->size >= need && ptr->flag == 0)
{
fit = ptr;
break;
}
ptr = ptr->next;
}
if (fit != NULL)
{
assign(fit, need);
printf("assigned successfully!\n");
}
else
{
puts("Sorry,there is no appropriate partion!");
free(fit);
}
}
void best_fit()
{
partion *fit = NULL;
partion *ptr = head;
int flag = 0; //flag 表示是否找到可分配的分区
while (ptr != NULL)
{
if (ptr->flag == 0 && ptr->size >= need)
{
if (flag == 0)
{
//只有遇到的第一个可分配分区回执行此操作
fit = ptr;
flag = 1;
}
else
{
//若遇到可分配且分区更小即更适合的则更新
if (ptr->size < fit->size)
{
fit = ptr;
}
}
}
ptr = ptr->next;
}
//先处理没找到合适分区的情况
if (flag == 0)
{
puts("Sorry,there is no appropriate partion!");
free(fit);
return;
}
//找到则分配
assign(fit, need);
puts("assigned successfully!");
}
void showMemoryInfo()
{
partion *ptr = head;
puts("\n\n---------------------------------------------");
puts("Here is the information of memory:");
puts("---------------------------------------------");
while (ptr != NULL)
{
printf("id:%21d%10c\nfront address:%10d%10c\n", ptr->id, '|', ptr->addr_front, '|');
printf("partion size:%11d%10c\n", ptr->size, '|');
printf("status:%17s%10c\n", ptr->flag == 0 ? "available" : "busy", '|');
puts("----------------------------------");
ptr = ptr->next;
}
puts("---------------------------------------------\n\n");
}
void assign(partion *ptr, int need)
{
if (need == ptr->size)
{
ptr->flag = 1;
return;
}
partion *assigned = createPartion(ptr->id, ptr->addr_front, need, 1);
assigned->next = ptr;
assigned->front = ptr->front;
changeIdValue(ptr, 1);
ptr->addr_front += need;
ptr->size -= need;
if (ptr->front != NULL)
{
ptr->front->next = assigned;
}
else
{
head = assigned;
}
ptr->front = assigned;
}
void recovery()
{
printf("please input the id to recovery:");
int id, flag = 0;
scanf("%d", &id);
partion *ptr = head;
while (ptr != NULL)
{
if (id == ptr->id)
{
flag = 1;
break;
}
ptr = ptr->next;
}
if (flag == 0)
{
puts("No such partion!");
return;
}
if (ptr->flag == 0)
{
puts("This partion is not busy!");
return;
}
if (ptr->front == NULL)
{
//第一个分区
if (ptr->next == NULL || ptr->next->flag == 1)
{
//后面不空或后面没有
ptr->flag = 0;
return;
}
if (ptr->next->flag == 0)
{
//后面空
ptr->size += ptr->next->size;
ptr->flag = 0;
if (ptr->next->next != NULL)
{
ptr->next->next->front = ptr;
}
ptr->next = ptr->next->next;
free(ptr->next);
return;
}
}
if (ptr->next == NULL)
{
//最后一个分区
if (ptr->front == NULL || ptr->front->flag == 1)
{
//前面不空或者前没有
ptr->flag = 0;
return;
}
if (ptr->front->flag == 0)
{
//前面为空
ptr->front->size += ptr->size;
ptr->front->next = NULL;
free(ptr);
return;
}
}
if (ptr->front->flag == 0 && ptr->next->flag == 0)
{
//上下都空
ptr->front->size += ptr->size + ptr->next->size;
ptr->front->next = ptr->next->next;
if (ptr->next->next != NULL)
{
ptr->next->next->front = ptr->front;
}
changeIdValue(ptr->front->next, -2); //更改id
free(ptr->next);
free(ptr);
return;
}
if (ptr->front->flag == 0 && ptr->next->flag == 1)
{
//上空下不空
ptr->front->size += ptr->size;
ptr->front->next = ptr->next;
ptr->next->front = ptr->front;
changeIdValue(ptr->front->next, -1);
free(ptr);
return;
}
if (ptr->front->flag == 1 && ptr->next->flag == 0)
{
//上不空下空
ptr->size += ptr->next->size;
if (ptr->next->next != NULL)
{
ptr->next->next->front = ptr;
}
partion *p_next = ptr->next; //保存一下下方为空的那个分区,以便一会释放
ptr->next = ptr->next->next;
ptr->flag = 0;
changeIdValue(ptr->next, -1);
free(p_next);
return;
}
if (ptr->front->flag == 1 && ptr->next->flag == 1)
{
//上下都不空
ptr->flag = 0;
return;
}
}
void changeIdValue(partion *ptr, int delta)
{
while (ptr != NULL)
{
ptr->id += delta;
ptr = ptr->next;
}
}
运行截图
首次适应


最佳适应


内存回收


如有错误欢迎指正
操作系统|C语言模拟实现首次适应和最佳适应两种内存分配算法以及内存回收的更多相关文章
- Java实现操作系统中四种动态内存分配算法:BF+NF+WF+FF
1 概述 本文是利用Java实现操作系统中的四种动态内存分配方式 ,分别是: BF NF WF FF 分两部分,第一部分是介绍四种分配方式的概念以及例子,第二部分是代码实现以及讲解. 2 四种分配方式 ...
- [操作系统知识储备,进程相关概念,开启进程的两种方式、 进程Queue介绍]
[操作系统知识储备,进程相关概念,开启进程的两种方式.进程Queue介绍] 操作系统知识回顾 为什么要有操作系统. 程序员无法把所有的硬件操作细节都了解到,管理这些硬件并且加以优化使用是非常繁琐的工作 ...
- c模拟内存分配算法(首次适应算法,最佳适应算法,最坏适应算法)
#include<bits/stdc++.h> using namespace std; /*定义内存的大小为100*/ #define MEMSIZE 100 /*如果小于此值,将不再分 ...
- 利用Telnet来模拟Http请求 有GET和POST两种
利用Telnet来模拟Http请求---访问百度. 1.打开"运行"->cmd进入命令环境: 2.输入"telnet www.baidu.c ...
- Java实现内存分配算法 FF(首次适应算法) BF(最佳适应算法)
一.概述 因为这次os作业对用户在控制台的输入输出有要求,所以我花了挺多的代码来完善控制台的显示. MemoryAlgorithm类里只是和控制台输入输出有关的操作,而对内存的所有逻辑操作都是用Mem ...
- Android JNI编程(五)——C语言的静态内存分配、动态内存分配、动态创建数组
版权声明:本文出自阿钟的博客,转载请注明出处:http://blog.csdn.net/a_zhon/. 目录(?)[+] 一:什么是静态内存什么又是动态内存呢? 静态内存:是指在程序开始运行时由编译 ...
- C语言模拟实现先来先服务(FCFS)和短作业优先(SJF)调度算法
说明 该并非实现真正的处理机调度,只是通过算法模拟这两种调度算法的过程. 运行过程如下: 输入进程个数 输入各个进程的到达事件 输入各个进程的要求服务事件 选择一种调度算法 程序给出调度结果:各进程的 ...
- c语言 变量的存储类别以及对应的内存分配?
<h4><strong>1.变量的存储类别</strong></h4>从变量值存在的角度来分,可以分为静态存储方式和动态存储方式.所谓静态存储方式指在程 ...
- C语言数据在内存分配
一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)— 程序运行时由编译器自动分配,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈.程序结束时由编译器自动释放 ...
- 图解Go语言内存分配
目录 基础概念 内存管理单元 内存管理组件 mcache mcentral mheap 内存分配流程 总结 参考资料 Go语言内置运行时(就是runtime),抛弃了传统的内存分配方式,改为自主管理. ...
随机推荐
- centos7源码编译安装nginx1.19并调优,向已安装的nginx添加新模块
目录 一.关于nginx 二.nginx的安装方式 三.源码编译安装nginx 3.1 下载nginx源码并解压 3.2 创建nginx用户和组 3.3 安装nginx编译环境(解决依赖问题) 3.4 ...
- git 安装 和 git 客户端的使用
git clone 命令 # 查前当前登录用户的一些基本信息: # 查看当前登录的账号:git config user.name # 修改当前登录的账号为xcj:git config --global ...
- 【C#】操作word 【Aspose.Words】
上图是要填充的word模板,就是一个接口说明文档.那个像书名号括起来的东西就是要替换的,这个东西并不是键盘输入的书名号,它是文档部件的一种,要插入这个东西需要: 打开模板word文件,用office打 ...
- 基于pulp的线性优化问题:微电网日前优化调度(复现)
摘录来源:(71条消息) 微电网日前优化调度入门:求解一道数学建模题_我不是玉的博客-CSDN博客 学习记录与复现 问题描述 问题出自第十届"中国电机工程学会杯"全国大学生电工数学 ...
- OC的引用计数
一.引用计数 引用计数是Objetive-C语言的内存管理机制,用于管理OC对象(通常指包含isa指针的结构体)的内存. 一个对象的引用计数为大于0的计数,表示这个对象被持有,不能被释放,当引用计数为 ...
- centos7下利用qemu搭建arm模拟器
1 目的 在centos7下使用qemu搭建arm模拟器. 参考博客: centos下利用qemu搭建arm模拟器 - 寒水司天 - 博客园 (cnblogs.com) 从零使用qemu模拟器搭建ar ...
- 混入 - Mixins
混入(mixins)是一种分发Vue组件中可复用功能的非常灵活的方式.混入对象可以包含任意组件选项.当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项. 混入分为:全局和局部 定义全局混 ...
- kettle从入门到精通 第四十八课 ETL之kettle webspoon
1.kettle自带的客户端spoon工具是cs架构,多人协同办公起来不是特别方便.当然spoon也可以通过文件仓库设置为database模式进行协同办公.每个人在自己电脑上安装&打开spoo ...
- Easysearch Chart 0.2.0都有哪些变化
Easysearch Chart 包更新了,让我们来看看都有哪些变化: Docker 镜像升级 Service 名称调整,支持 NodePort 模式部署 现在让我们用 NodePort 模式部署一下 ...
- .NET FRAMEWORK Entity Framework,EF 手动DB FIRST,不使用设计器
环境: VS2019 SQL SERVER 2012 一.在数据库(db1)创建表结构 "db1"是数据库名,"Table1"是表名. USE [db1] GO ...