两种算法

  • 首次适应

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

  • 最佳适应

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

程序代码

#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. 腾讯云服务器sdk

    参考:https://cloud.tencent.com/document/product/494/7244 pip install -i https://mirrors.tencent.com/py ...

  2. 二:nacos 的服务注册

    一:怎么引用依赖 dependencyManagement:spring cloud alibaba 的版本,由于spring cloud alibaba 还未纳入spring cloud 的主版本管 ...

  3. Android 12(S) MultiMedia Learning(十)ACodec & OMX

    这一节的学习分为三块内容,omx hidl service用法.OMX架构.ACodec中的buffer分配. 1.omx hidl service system可以借助vndbinder来访问ven ...

  4. Asp-Net-Core学习笔记:身份认证入门 _

    前言 过年前我又来更新了~ 我就说了最近不是在偷懒吧,其实这段时间还是有积累一些东西的,不过还没去整理-- 所以只能发以前没写完的一些笔记出来 就当做是温习一下啦 PS:之前说的红包封面我还没搞,得抓 ...

  5. C#使用WebView2替代Electron

    C#想要实现Electron那样混合桌面程序可以用以下几个库.本文使用EdgeSharp NanUI​github.com/NetDimension/NanUI Photino​github.com/ ...

  6. FreeSWITCH使用soundtouch进行变声

    操作系统 :CentOS 7.6_x64 FreeSWITCH版本 :1.10.9   FreeSWITCH里面有个mod_soundtouch模块,支持通话实时变声,今天整理下CentOS 7环境下 ...

  7. pidstat 命令查看nginx上下文切换

    pidstat -w -p 711 1 [root@leilei ~]# ps -ef|grep nginx root 13974 1 0 14:23 ? 00:00:00 nginx: master ...

  8. 使用final shell 连接使用 ubuntu server linux

    书接上回,VM 安装ubuntu server:https://www.cnblogs.com/runliuv/p/16880599.html 1.从 https://www.hostbuf.com/ ...

  9. 打开TLS 1.1和1.2而不影响其他协议

    打开TLS 1.1和1.2而不影响其他协议 System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 ...

  10. Kafka多维度调优

    优化金字塔 应用程序层面 框架层面(Broker层面) JVM层面 操作系统层面 应用程序层面:应当优化业务代码合理使用kafka,合理规划主题,合理规划分区,合理设计数据结构: 框架层面:在不改动源 ...