模拟操作系统内存动态分配问题

模拟了操作系统作业中内存动态分配问题。是一个简单的实现。
 

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <tgmath.h>
#include <string.h>
#define  n  10 //假定系统允许的最大作业数量为n
#define  m  10 //假定系统允许的空闲区表最大为m
#define minsize 1000
 typedef struct workPcb{
    char name[4];//name是字符串的首地址,char * a a保存着储存字符串的地址
    double length;
} workPcb;
 struct{
     char name[4];
     double address;   	//已分分区起始地址
     double length;   	//已分分区长度,单位为字节
     int flag;       	//已分配区表登记栏标志,“0”表示空栏目,实验中只支持一个字符的作业名
}used_table[n];  	//已分配区表
//空闲区表的定义:

 struct
{    double address;   	//空闲区起始地址
     double length;   	//空闲区长度,单位为字节
     int flag;      	//空闲区表登记栏标志,用“0”表示空栏目,用“1”表示未分配
}free_table[m];  	//空闲区表
//找到最小的

double freeArea=100*2*2*2*2*2*2*2*2*2*2;
void distribution(workPcb* workPcb){
    int k=-1,i=0;
    while(i<=m){
        if(free_table[i].flag==1){//当第i个分区没有被分配时
            if(free_table[i].length>=workPcb->length){//满足长度的分区
                if(k=-1)//找出满足条件的最小的分区
                    k=i;
                else{
                    if(free_table[i].length<free_table[k].length){
                        k=i;
                    }
                }
            }
        }
        i++;
    }
    //已经遍历完所有的分区
    if(k!=-1){
        double ad,xk;
        if(free_table[k].length-workPcb->length<=minsize){//当满足最小值的时候全部分配
            free_table[k].flag=0;
            ad=free_table[k].address;//分配的起始地址
            xk=free_table[k].length;//分配的长度
            free_table[k].length=0;

        }else{
            ad=free_table[k].address;
            free_table[k].address+=workPcb->length;
            xk=workPcb->length;
            free_table[k].length=free_table[k].length-workPcb->length;
        }
        //寻找空闲的已分配表
        int j=0;
        while(j<=9){
            if(used_table[j].flag==0){//如果有空闲的已分配表那么就分配
                strcpy(used_table[j].name, workPcb->name);
                used_table[j].address=ad;
                used_table[j].length=xk;
                used_table[j].flag=1;
                break;
            }
            else
                j++;
        }//如果j<10就分配成功
        if(j!=10){
            printf("分配成功\n");

        }else{//如果分配不成功,那么还回空闲分配区的长度

            if(free_table[k].length==0){
                free_table[k].length=xk;
            }else{
                free_table[k].length=free_table[k].length+workPcb->length;
                used_table[j].flag=0;
                free_table[k].address-=workPcb->length;
            }
            printf("分配空间不足");
        }

    }else{
        printf("空闲空间不足,失败\n");
    }

}
void reclaim(workPcb *J){
    int s=0,a=0;
    double S,L;
    while(s<=9){

    a=strcmp(J->name,used_table[s].name);


    if(a==0){//找到作业与未找到作业
        S=used_table[s].address;
        L=used_table[s].length;
        used_table[s].flag=0;
        int j=-1;//相邻下空闲区栏
        int k=-1;
        double upS,doS;//相邻上空闲区栏
        upS=used_table[s].address+used_table[s].length;//应该的上分区和下分区//应该的上分区和下分区
        int q=0;
        while(q<=9){//判断有没有上下分区
            if(free_table[q].address==upS){
                k=q;
            }
            if(free_table[q].address+free_table[q].length==S){
                j=q;
            }
            q++;
        }
        if(k!=-1){//存在上分区
            if(j!=-1){//两个分区都存在
                free_table[k].length=L+free_table[k].length+free_table[j].length;
                free_table[k].address-=L+free_table[j].length;
                free_table[j].flag=0;
                  printf("回收成功");
            }
            else{//只存在上分区
                free_table[k].length=L+free_table[k].length;
                free_table[k].address-=L;
                  printf("回收成功");
            }
        }else{
            if(j!=-1){//只存在下分区
                free_table[j].length=L+free_table[j].length;
                  printf("回收成功");
            }else{//哪个分区都不存在
                int t=0;
                while(t<=9){//寻找一块分配表里的新地方
                    if(free_table[t].flag==0){
                        break;
                    }
                    t++;
                }
                if(t==10){
                    used_table[s].flag=1;
                    printf("作业回收失败,空闲分区表不足");
                }else{//设置属性
                    free_table[t].address=S;
                    free_table[t].length=L;
                    free_table[t].flag=1;
                    printf("回收成功");
                }


            }

        }
    break;//找到了就break了
    }else
        s++;

    }
    if(s==10){
        printf("未找到作业");
    }

}


int main(){
    int jud=1;
    int choice=3;
    printf("欢迎进入作业分配与回收的程序,1为分配,2为回收,3退出程序,4查看空闲表和已分配表\n");
    scanf("%d",&choice);
    workPcb workPcb;//一个作业
    free_table[0].address=10*2*2*2*2*2*2*2*2*2*2;//除去了操作系统后的低地址
    free_table[0].length=freeArea;//初始化空闲表
    free_table[0].flag=1;//空闲区1代表可分配
    for(int i=0;i<=9;i++){
        used_table[i].flag=0;
    }
    //初始化已分配表 已分配表0代表空

    while(jud){
        switch(choice){
            case 1:{
                printf("请输入作业名,作业长度\n");
                scanf("%s%lf",&workPcb.name,&workPcb.length);//填写作业名与长度
                printf("作业名:%s作业大小:%lf\n",workPcb.name,workPcb.length);
                distribution(&workPcb);
                break;
            }
            case 2:{
                printf("请输入作业名\n");
                scanf("%s",&workPcb.name);//填写作业名与长度
                reclaim(&workPcb);
                break;
            }
            case 3:{
                jud=0;
                printf("拜拜");
                break;

            }
            case 4:{

                printf("------------空闲表状态\n");
                for(int i=0;i<=9;i++){
                    if(free_table[i].flag==0){
                        free_table[i].address=0;
                        free_table[i].length=0;
                    }
                    printf("空闲区域开始地址:%lf大小:%lf状态:%d\n",free_table[i].address,free_table[i].length,free_table[i].flag);
                }
                printf("------------已分配表状态\n");
                for(int i=0;i<=9;i++){
                         if(used_table[i].flag==0){
                        used_table[i].name[0]=0;
                        used_table[i].address=0;
                        used_table[i].length=0;
                    }
                    printf("已分配区域作业名:%s开始地址:%lf大小:%lf状态:%d\n",used_table[i].name,used_table[i].address,used_table[i].length,used_table[i].flag);
                }
                break;
            }
            default:{
            printf("输入有错误,请重试\n");
            }
        }
        if(jud!=0){
        printf("欢迎进入作业分配与回收的程序,1为分配,2为回收,3退出程序,4查看作业状态\n");
        scanf("%d",&choice);
        }
    }
    return 0;   //进行分配任务
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m0_65380540

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值