操作系统|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),抛弃了传统的内存分配方式,改为自主管理. ...
随机推荐
- k8s多集群切换:使用kubeconfig文件管理多套kubernetes(k8s)集群
目录 一.系统环境 二.前言 三.kubeconfig文件 四.kubernetes(k8s)多集群切换 一.系统环境 服务器版本 docker软件版本 CPU架构 CentOS Linux rele ...
- CSS——圆角
例子1: <!DOCTYPE html> <html lang="en"> <head> <style> div { width: ...
- 如何用 Unity 做出一只赛博宠物
推荐的一些学习资料 unity 官方文档:Unity 用户手册 (2019.4LTS) - Unity 手册 视频教程:https://www.bilibili.com/video/BV1zB4y1C ...
- Uni-app极速入门(二) - 登录demo
需求 背景 1.进入小程序,默认页面判断用户是否已经登录,已经登录则进入首页,没有登录则进入登录页面 2.首页为tabbar,包括首页和设置页,设置页可以退出登录,回到登录页面 页面流转 graph ...
- 基于pulp的线性优化问题:微电网日前优化调度(复现)
摘录来源:(71条消息) 微电网日前优化调度入门:求解一道数学建模题_我不是玉的博客-CSDN博客 学习记录与复现 问题描述 问题出自第十届"中国电机工程学会杯"全国大学生电工数学 ...
- 007. gitlab仓库管理
1. gitlab创建组 创建后: 组管理: 组创建完成后,开始创建用户 2. gtilab创建用户 这里无法直接创建密码,需要创建用户后在对用户进行操作修改密码 密码和权限设置,取消和开启创建组权限 ...
- nginx37条优化
nginx优化: 1. cpu:核心配置 方法1: worker_processes auto; 自动调用[推荐] 方法2: worker_processes 4; 手工配置 检查CPU核心:yum ...
- 为UIView自定义Xib
一.需求 通过Interface Builder的形式创建Xib,并将其和一个UIView的子类绑定,如何实现? 二.解决 这个问题通过搜索,有大量的答案,大概答案的代码如下: 也就是在你的子类中,在 ...
- numpy基础--线性代数
以下代码的前提:import numpy as np 线性代数(如矩阵乘法.矩阵分解.行列式以及其他方阵数学等)是任何数组库的重要组成部分.numpy提供了一个用于矩阵乘法的dot函数(既是一个数组方 ...
- JavaScript实现防抖节流函数
review 防抖函数 防抖函数一般是短时间内多次触发,但是只有最后一次触发结束后的delay秒内会去执行相对应的处理函数. 相当于一个赛道里面一次只能跑一辆赛车,如果此时已经有一辆赛车在跑道里面跑, ...