homework

这是一个内存管理模拟系统的实现,包括了多种内存分配算法(首次适应、最佳适应、最差适应、下次适应)以及内存碎片整理。用户可以设置内存大小、选择分配算法,创建和终止进程,查看内存使用情况。系统采用链表数据结构来表示内存空闲块和已分配块,实现了动态内存分配和回收功能。
摘要由CSDN通过智能技术生成

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>

#define PROCESS_NAME_LEN 32   /*进程名称的最大长度*/
#define MIN_SLICE 10          /*最小碎片的大小*/
#define DEFAULT_MEM_SIZE 1024 /*默认内存的大小*/
#define DEFAULT_MEM_START 0   /*默认内存的起始位置*/

/* 内存分配算法 */
#define MA_FF 1
#define MA_BF 2
#define MA_WF 3
#define MA_NF 4

int mem_size = DEFAULT_MEM_SIZE; /*内存大小*/
int ma_algorithm = MA_FF;        /*当前分配算法*/
int flag = 0;                    /*设置内存大小标志*/
static int pid = 0;              /*初始pid*/
int algorithm;

/*描述每一个空闲块的数据结构*/
struct free_block_type {
    int size;
    int start_addr;
    struct free_block_type *next;
};

/*指向内存中空闲块链表的首指针*/
struct free_block_type *free_block;
struct free_block_type *NF_tmp = NULL;

/*每个进程分配到的内存块的描述*/
struct allocated_block {
    int pid;
    int size;
    int start_addr;
    char process_name[PROCESS_NAME_LEN];
    struct allocated_block *next;
};
/*进程分配内存块链表的首指针*/
struct allocated_block *allocated_block_head = NULL;

struct allocated_block *find_process(int id) {
    struct allocated_block *p;
    p = allocated_block_head;
    while (p != NULL) {
        if (p->pid == id)
            return p;
        p = p->next;
    }
    return NULL;
}

void swap(int *p, int *q) {
    int temp;

    temp = *p;
    *p = *q;
    *q = temp;

    return;
}

void do_exit() { exit(0); }

/*初始化空闲块,默认为一块,可以指定大小及起始地址*/
struct free_block_type *init_free_block(int mem_size) {
    struct free_block_type *fb;

    fb = (struct free_block_type *)malloc(sizeof(struct free_block_type));
    if (fb == NULL) {
        printf("No mem\n");
        return NULL;
    }
    fb->size = mem_size;
    fb->start_addr = DEFAULT_MEM_START;
    fb->next = NULL;
    // NF_tmp = fb;
    return fb;
}

/*显示菜单*/
void display_menu() {
    printf("\n");
    printf("1 - Set memory size (default=%d)\n", DEFAULT_MEM_SIZE);
    printf("2 - Select memory allocation algorithm\n");
    printf("3 - New process \n");
    printf("4 - Terminate a process \n");
    printf("5 - Display memory usage \n");
    printf("0 - Exit\n");
}

/*设置内存的大小*/
set_mem_size() {
    int size;
    if (flag != 0) { //防止重复设置
        printf("Cannot set memory size again\n");
        return 0;
    }
    printf("Total memory size =");
    scanf("%d", &size);

    if (size > 0) {
        mem_size = size;
        free_block->size = mem_size;
    }
    flag = 1;
    return 1;
}

/*按FF算法重新整理内存空闲块链表*/
rearrange_FF() {
    struct free_block_type *tmp, *work;
    printf("Rearrange free blocks for FF \n");
    tmp = free_block;
    if (ma_algorithm == MA_FF || NF_tmp == NULL)
        NF_tmp = free_block;
    while (tmp != NULL) {
        work = tmp->next;
        while (work != NULL) {
            if (work->start_addr < tmp->start_addr) { /*地址递增*/
                swap(&work->start_addr, &tmp->start_addr);
                swap(&work->size, &tmp->size);
            }

            work = work->next;
        }
        tmp = tmp->next;
    }
}

/*按BF最佳适应算法重新整理内存空闲块链表*/

rearrange_BF() {
    struct free_block_type *tmp, *work;
    printf("Rearrange free blocks for BF \n");
    tmp = free_block;
    NF_tmp = free_block;
    while (tmp != NULL) {
        work = tmp->next;
        while (work != NULL) {
            if (work->size > tmp->size) { /*地址递增*/
                swap(&work->start_addr, &tmp->start_addr);
                swap(&work->size, &tmp->size);
            }

            work = work->next;
        }
        tmp = tmp->next;
    }
}

/*按WF算法重新整理内存空闲块链表*/

rearrange_WF() {
    struct free_block_type *tmp, *work;
    printf("Rearrange free blocks for WF \n");
    tmp = free_block;
    NF_tmp = free_block;
    while (tmp != NULL) {
        work = tmp->next;
        while (work != NULL) {
            if (work->size > tmp->size) { /*地址递增*/
                swap(&work->start_addr, &tmp->start_addr);
                swap(&work->size, &tmp->size);
            } else
                work = work->next;
        }
        tmp = tmp->next;
    }
}

/*按指定的算法整理内存空闲块链表*/
rearrange(int algorithm) {
    switch (algorithm) {
    case MA_FF:
        rearrange_FF();
        break;
    case MA_BF:
        rearrange_BF();
        break;
    case MA_WF:
        rearrange_WF();
        break;
    case MA_NF:
        rearrange_FF();
        break;
    }
}

/* 设置当前的分配算法 */
void set_algorithm() {

    printf("\t1 - First Fit\n");
    printf("\t2 - Best Fit \n");
    printf("\t3 - Worst Fit \n");
    printf("\t4 - Next Fit \n");
    scanf("%d", &algorithm);
    if (algorithm >= 1 && algorithm <= 4)
        ma_algorithm = algorithm;
    else
        printf("选择不正确!\n");
    //按指定算法重新排列空闲区链表
    rearrange(ma_algorithm);
}

/*分配内存模块*/
int allocate_mem(struct allocated_block *ab, int ab_size) {
    struct free_block_type *fbt, *pre, *temp, *work, *F = NULL;
    int request_size = ab_size;
    if (NF_tmp == free_block || NF_tmp == NULL) {
        F = NULL;
        NF_tmp = free_block;
    } else
        F = NF_tmp;
    fbt = NF_tmp;
    pre = fbt;
    do {
        if (F != NULL && fbt == NULL)
            fbt = free_block;
        if (fbt->size >= request_size) {
            NF_tmp = fbt;
            if (fbt->size - request_size >=
                MIN_SLICE) /*分配后空闲空间足够大,则分割*/
            {
                mem_size -= request_size;
                fbt->size -= request_size;
                ab->start_addr = fbt->start_addr;
                fbt->start_addr += request_size;
                NF_tmp = fbt;

            } else if ((fbt->size - request_size) < MIN_SLICE)
            /*分割后空闲区成为小碎片,一起分配*/
            {

                mem_size -= fbt->size;
                if (pre == free_block)
                    free_block = fbt->next;
                else if (pre == fbt)
                    for (pre = free_block; pre->next != NULL; pre = pre->next)
                        if (pre->next == fbt)
                            break;
                pre->next = fbt->next;
                NF_tmp = fbt->next;
                ab->start_addr = fbt->start_addr;
                ab->size = fbt->size;
                free(fbt);
            } else {
                temp = free_block;
                while (temp != NULL) {
                    work = temp->next;

                    if (work !=
                        NULL) /*如果当前空闲区与后面的空闲区相连,则合并*/
                    {
                        if (temp->start_addr + temp->size == work->start_addr) {
                            temp->size += work->size;
                            temp->next = work->next;
                            if (NF_tmp == work)
                                NF_tmp = temp;
                            free(work);
                            continue;
                        }
                    }

                    temp = temp->next;
                }
                rearrange(algorithm); /*重新按当前的算法排列空闲区*/
            }
            return 1;
        }
        pre = fbt;
        fbt = fbt->next;
    } while (fbt != F);
    return -1;
}

/*创建新的进程,主要是获取内存的申请数量*/
new_process() {
    struct allocated_block *ab;
    int size;
    int ret;
    ab = (struct allocated_block *)malloc(sizeof(struct allocated_block));
    if (!ab)
        exit(-5);
    ab->next = NULL;
    pid++;
    sprintf(ab->process_name, "PROCESS-%02d", pid);
    ab->pid = pid;

    printf("Memory for %s:", ab->process_name);
    scanf("%d", &size);
    if (size > 0)
        ab->size = size;
    else
        printf("输入大小不合法!\n");
    ret = allocate_mem(ab, ab->size); /* 从空闲区分配内存,ret==1表示分配ok*/
    /*如果此时allocated_block_head尚未赋值,则赋值*/
    if ((ret == 1) && (allocated_block_head == NULL)) {
        allocated_block_head = ab;
        return 1;
    }
    /*分配成功,将该已分配块的描述插入已分配链表*/
    else if (ret == 1) {
        ab->next = allocated_block_head;
        allocated_block_head = ab;
        return 2;
    } else if (ret == -1) { /*分配不成功*/
        printf("Allocation fail\n");
        free(ab);
        return -1;
    }
    return 3;
}

/*将ab所表示的已分配区归还,并进行可能的合并*/
int free_mem(struct allocated_block *ab) {
    int algorithm = ma_algorithm;
    struct free_block_type *fbt, *work;

    fbt = (struct free_block_type *)malloc(sizeof(struct free_block_type));
    if (!fbt)
        return -1;
    fbt->size = ab->size;
    fbt->start_addr = ab->start_addr;
    /*插入到空闲区链表的头部并将空闲区按地址递增的次序排列*/
    fbt->next = free_block;
    free_block = fbt;
    rearrange(MA_FF);
    fbt = free_block;
    while (fbt != NULL) {
        work = fbt->next;
        if (work != NULL) {
            /*如果当前空闲区与后面的空闲区相连,则合并*/
            if (fbt->start_addr + fbt->size == work->start_addr) {
                fbt->size += work->size;
                fbt->next = work->next;
                if (NF_tmp == work)
                    NF_tmp = fbt;
                free(work);
                continue;
            }
        }
        fbt = fbt->next;
    }
    rearrange(algorithm); /*重新按当前的算法排列空闲区*/
    return 1;
}

/*释放ab数据结构节点*/
int dispose(struct allocated_block *free_ab) {
    struct allocated_block *pre, *ab;

    if (free_ab == allocated_block_head) { /*如果要释放第一个节点*/
        allocated_block_head = allocated_block_head->next;
        free(free_ab);
        return 1;
    }

    pre = allocated_block_head;
    ab = allocated_block_head->next;

    while (ab != free_ab) {
        pre = ab;
        ab = ab->next;
    }
    pre->next = ab->next;
    free(ab);
    return 2;
}

/* 显示当前内存的使用情况,包括空闲区的情况和已经分配的情况 */
display_mem_usage() {
    struct free_block_type *fbt = free_block;
    struct allocated_block *ab = allocated_block_head;
    printf("------------------------------------------------------\n");
    printf("\tFree Memory:\n");

    if (fbt == NULL) {
        printf("内存已满,无空闲!!!\n");
    }

    /* 显示空闲区 */
    else
        printf("%20s %20s\n", "      start_addr", "       size");
    while (fbt != NULL) {
        printf("%20d %20d\n", fbt->start_addr, fbt->size);
        fbt = fbt->next;
    }
    /* 显示已分配区 */
    printf("------------------------------------------------------\n");

    printf("\nUsed Memory:\n");
    printf("%10s %20s %20s %10s\n", "PID", "ProcessName", "start_addr",
           " size");
    while (ab != NULL) {
        printf("%10d %20s %20d %10d\n", ab->pid, ab->process_name,
               ab->start_addr, ab->size);
        ab = ab->next;
    }
    printf("------------------------------------------------------\n");
    return 0;
}

/*删除进程,归还分配的存储空间,并删除描述该进程内存分配的节点*/
kill_process() {
    struct allocated_block *ab;
    int pid;
    printf("Kill Process, pid=");
    scanf("%d", &pid);
    ab = find_process(pid);
    if (ab != NULL) {
        free_mem(ab); /*释放ab所表示的分配区*/
        dispose(ab);  /*释放ab数据结构节点*/
    }
}

int main() {
    char choice;
    pid = 0;
    free_block = init_free_block(mem_size); //初始化空闲区
    for (;;) {
        display_menu();     //显示菜单
        fflush(stdin);      //清空输入缓冲区
        choice = getchar(); //获取用户输入
        switch (choice) {
        case '1':
            set_mem_size();
            break; //设置内存大小
        case '2':
            set_algorithm();
            flag = 1;
            break; //设置分配算法
        case '3':
            new_process();
            flag = 1;
            break; //创建新进程
        case '4':
            kill_process();
            flag = 1;
            break; //删除进程
        case '5':
            display_mem_usage();
            flag = 1;
            break; //显示内存使用
        case '0':
            do_exit();
            exit(0);
            break; //释放链表并退出
        default:
            break;
        }
    }
    return 0;
}
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值