可变分区存储管理-使用双向链表实现循环首次适应法

操作系统 实验一 可变分区存储管理-循环首次适应法文章目录操作系统 实验一 可变分区存储管理-循环首次适应法摘要算法思想和概要设计算法思想分配算法释放算法概要设计初始化分配释放数据结构与变量说明双向链表的表项:全局指针源程序链表结构体与全局变量的定义循环首次适应法的分配函数循环首次适应法的释放函数coremap链表的初始化程序输出链表的内容主程序测试测试样例设计基本功能测试设计出错处理测试设计测...
摘要由CSDN通过智能技术生成

可变分区存储管理-循环首次适应法

摘要

本次试验中,使用双向链表的数据结构,用 C 语言成功实现了可变分区存储管理中的循环首次适应法,实现了对内存区的分配和释放管理。并且考虑了很多分配和释放内存区时的错误,如分配时内存不足,释放越界,重复释放等问题,并给出了合适的解决办法。通过本次试验,可以加深理解可变分区存储管理与用指针和结构体实现双向链表和在链表上的基本操作。

算法思想和概要设计

算法思想
分配算法

程序采用循环首次适应法的思想,把空闲表设计成连接结构的循环队列,各空闲区仍按地址从低到高的次序登记在空闲区的管理队列中,同时设置一个起始查找指针,指向循环队列中的一个空闲区表项。

循环首次适应法分配时总是从起始查找指针所指的表项开始查找,第一次找到满足要求的空闲区时,就分配所需大小的空闲区,修改表项,并调整起始查找指针,使其指向队伍中被分配的后面那块空闲区。下次分配时就从新指向的那块空闲区开始查找。

释放算法

循环首次适应法的释放算法针对以下四种情况采取四种策略:

  • 释放区与前空闲区相连:合并前空闲区和释放区构成一块大的新空闲区,并修改前空闲区表项的地址和大小属性。
  • 与前空闲区和后空闲区都相连:将三块空闲区合并成一块空闲区,并修改前空闲区表项的地址和大小属性。
  • 仅与后空闲区相连:与后空闲区合并,并修改后空闲区表项的地址和大小属性。
  • 与前、后空闲区皆不相连:在前、后空闲区表项中间插入一个新的表项。
概要设计

主程序中,先向真实主存申请一块固定大小的内存,再用这块内存初始化空闲区双向链表。此时双向链表中只有一个表项,其前向指针与后向指针都指向自身,大小属性等于申请的内存的大小。之后用键盘输入指令来模拟程序向主存申请或释放内存。

初始化

双向链表中只有一个表项,其前向指针与后向指针都指向自身,大小属性等于申请的内存的大小,地址属性等于申请的内存的基地址。
在这里插入图片描述

分配

查找指针不断前移直到找到合适的空闲区。如果沿双向链表找了一圈仍未找到,就认为不存在合适的空闲区,拒绝分配并报错。

释放

由于使用了基地址,所以指令中输入相对地址进行释放。值得一提的是,释放时考虑了多个可能出现的错误,如重复释放已空闲区域,释放区位置与已存在的空闲区部分重合等问题。

在这里插入图片描述

数据结构与变量说明

双向链表的表项:
/*双向链表的定义*/
struct map
{
   
    unsigned m_size;					//空闲区大小
    char *m_addr;							//空闲区首地址
    struct map *next, *prior;	//后向指针与前向指针
};
全局指针
struct map *coremap;    //链表起始指针
struct map *flag;       //起始查找指针

源程序

链表结构体与全局变量的定义
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
//#include <malloc.h>

#define MEMSIZE 1000

/*双向链表的定义*/
struct map
{
   
    unsigned m_size;
    char *m_addr;
    struct map *next, *prior;
};

struct map *coremap;    //链表起始指针
struct map *flag;       //起始查找指针
循环首次适应法的分配函数
/*循环适应的分配函数*/
char *lmalloc(unsigned size)
{
   
    register char *a;
    register struct map *bp;
    bp = flag;
    do
    {
   
      if(bp->m_size >= size)
        {
   
            a = bp->m_addr;
            bp->m_addr += size;
            flag = bp->next;
            if((bp->m_size -= size) == 0)   // 删除用光的空闲区项
            {
   
                bp->prior->next = bp->next;
                bp->next->prior = bp->prior;
                free(bp);
            }
            printf("Success: lmalloc size: %d, addr:%p\n", size, a);    //分配空间成功
            return(a);
        }
        bp = bp->next;
    }while(bp != flag);
    printf("Error: There is no appropriate memory to be allocated for the size!\n");    		//分配空间失败
    return(0);
}
循环首次适应法的释放函数
/* 循环首次适应的释放函数 */
char *lfree(unsigned size, char *aa)
{
   
    struct map *bp;
    char *a; 
    a = aa;
    for(bp = coremap; bp->m_addr <= a; bp = bp->next);
    if (bp->prior->m_addr + bp->prior->m_size >= a && a >= bp->prior->m_addr && bp->next != bp) /* 情况1,2 */
    {
   
        if(a + size > bp->m_addr + bp->m_size)  // 防止向下溢出一整个空闲项
        {
   
            printf("Error: Release area out of bounds!\n");
            return(0);
        }
        else if(bp->prior->m_addr + bp->prior->m_size > a + size)   // 防止重复释放已空闲的区域
        {
   
            printf("Error: Already released!\n");
            return(0);
        
  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值