两种算法

  • 首次适应

    首次适应算法从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给作业,这种方法目的在于减少查找时间。为适应这种算法,空闲分区表(空闲区链)中的空闲分区要按地址由低到高进行排序。该算法优先使用低址部分空闲区,在低址空间造成许多小的空闲区,在高地址空间保留大的空闲区。

  • 最佳适应

    最佳适应算法是指从全部空闲区中找出能满足作业要求且大小最小的空闲分区的一种计算方法,这种方法能使碎片尽量小。

程序代码

#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语言模拟实现首次适应和最佳适应两种内存分配算法以及内存回收的更多相关文章

  1. Java实现操作系统中四种动态内存分配算法:BF+NF+WF+FF

    1 概述 本文是利用Java实现操作系统中的四种动态内存分配方式 ,分别是: BF NF WF FF 分两部分,第一部分是介绍四种分配方式的概念以及例子,第二部分是代码实现以及讲解. 2 四种分配方式 ...

  2. [操作系统知识储备,进程相关概念,开启进程的两种方式、 进程Queue介绍]

    [操作系统知识储备,进程相关概念,开启进程的两种方式.进程Queue介绍] 操作系统知识回顾 为什么要有操作系统. 程序员无法把所有的硬件操作细节都了解到,管理这些硬件并且加以优化使用是非常繁琐的工作 ...

  3. c模拟内存分配算法(首次适应算法,最佳适应算法,最坏适应算法)

    #include<bits/stdc++.h> using namespace std; /*定义内存的大小为100*/ #define MEMSIZE 100 /*如果小于此值,将不再分 ...

  4. 利用Telnet来模拟Http请求 有GET和POST两种

    利用Telnet来模拟Http请求---访问百度.       1.打开"运行"->cmd进入命令环境:       2.输入"telnet www.baidu.c ...

  5. Java实现内存分配算法 FF(首次适应算法) BF(最佳适应算法)

    一.概述 因为这次os作业对用户在控制台的输入输出有要求,所以我花了挺多的代码来完善控制台的显示. MemoryAlgorithm类里只是和控制台输入输出有关的操作,而对内存的所有逻辑操作都是用Mem ...

  6. Android JNI编程(五)——C语言的静态内存分配、动态内存分配、动态创建数组

    版权声明:本文出自阿钟的博客,转载请注明出处:http://blog.csdn.net/a_zhon/. 目录(?)[+] 一:什么是静态内存什么又是动态内存呢? 静态内存:是指在程序开始运行时由编译 ...

  7. C语言模拟实现先来先服务(FCFS)和短作业优先(SJF)调度算法

    说明 该并非实现真正的处理机调度,只是通过算法模拟这两种调度算法的过程. 运行过程如下: 输入进程个数 输入各个进程的到达事件 输入各个进程的要求服务事件 选择一种调度算法 程序给出调度结果:各进程的 ...

  8. c语言 变量的存储类别以及对应的内存分配?

    <h4><strong>1.变量的存储类别</strong></h4>从变量值存在的角度来分,可以分为静态存储方式和动态存储方式.所谓静态存储方式指在程 ...

  9. C语言数据在内存分配

    一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)— 程序运行时由编译器自动分配,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈.程序结束时由编译器自动释放 ...

  10. 图解Go语言内存分配

    目录 基础概念 内存管理单元 内存管理组件 mcache mcentral mheap 内存分配流程 总结 参考资料 Go语言内置运行时(就是runtime),抛弃了传统的内存分配方式,改为自主管理. ...

随机推荐

  1. OpenAI“杀疯了”,GPT–4o模型保姆级使用教程!一遍就会!

    5月14日凌晨1点,OpenAI发布了名为GPT-4o 最新的大语言模型,再次引领了人工智能领域的又一创新浪潮,让整个行业都为之震动. 据OpenAI首席技术官穆里-穆拉提(Muri Murati)表 ...

  2. sass 混合指令 (Mixin Directives)详解

    ​ 混合指令(Mixin)用于定义可重复使用的样式,避免了使用无语意的 class,比如 .float-left.混合指令可以包含所有的 CSS 规则,绝大部分 Sass 规则,甚至通过参数功能引入变 ...

  3. Python RabbitMQ Demo

    fanout消息订阅模式 生产者 # 生产者代码 import pika credentials = pika.PlainCredentials('guest', 'guest') # mq用户名和密 ...

  4. tkinter小例子

    from tkinter import * def on_click(): label['text'] = text.get() root = Tk(className='hello') root.m ...

  5. H.265码流解析

    这一篇内容旨在对H.265码流中的一些概念做简单了解,部分概念与H.264相同,本篇中将不再重复. 1.NALU H.265(HEVC)码流的NALU结构和AVC有一些不同,属于增强版,HEVC NA ...

  6. Newtonsoft.Json解决中文编码问题

    Newtonsoft.Json解决中文编码 默认Newtonsoft.Json序列化对象后,返回的中文未进行编码. 需要将编码转换的话,需要 1 2 3 4 5 6 7 var json = Json ...

  7. 论elasticsearch在Windows环境的安装

    前置需求 一台电脑(我用的是Windows),有网 第一步:下载并安装 去java官网下载开发版java(考虑到可能有小白,我暂且这么说) java官网下载链接:https://www.oracle. ...

  8. 第一次至第三次PTAJava大作业分析

    (1)前言: 三次题目集的知识点: 正则表达式(Regular Expression,简称Regex或RegExp)是一个强大的文本处理工具,用于匹配.查找和替换字符串.以下是正则表达式的主要知识点总 ...

  9. idea 使用 mvn clean package 报错 Could not create local repository at

    使用 mac 版本的 idea 打包使用打包命令 mvn clean package 总是报错: [ERROR] Could not create local repository at /Repos ...

  10. 10位,13位时间戳转为C#.NET格式时间 DateTime

    10位,13位时间戳转为C#.NET格式时间 DateTime - public static DateTime ToDateTime( string timestamp) { var tz = Ti ...