动态分区分配 存储管理的模拟程序设计

动态分区分配
一、实验目标
开发一个C语言程序实现内存空间管理的动态分区分配方案。
二、实验原理
动态分区分配:根据进程的实际需要,动态地创建分区为之分配内存空间,在实现动态分区分配时,将涉及分区分配中所使用的数据结构,分区分配算法和分区的分配与回收操作等问题。
1) 分区分配中的数据结构
 空闲分区表:一个数据表,用于记录每个空闲块的情况,如起始地址、大小、使用情况等;
 空闲分区链表:把所有的空闲分区链接成一个链表,便于内存空间查看与分配回收。
2) 内存分配过程
利用分配算法找到满足要求的内存块,设请求的内存大小为size:
 若找到的空闲分区的大小等于size,完全分配;
 若找到的空闲分区大小大于size,且一分为二后,剩余大小小于1K,则不再分割,作为整体进行分配;否则一分为二,剩余部分仍然作为空闲分区存在;
 若无满足要求空闲分区,则分配失败
3) 分配算法
 首次适应法:空闲分区按首地址递增次序组织,每次查找时从链首出发,寻找满足要求的内存块。
 最佳适应法:空闲分区按空闲分区大小址递增次序组织,每次查找时从链首出发,寻找满足要求的最小内存块进行分配。
 最坏适应法:空闲分区按空闲分区大小递减次序组织,每次查找时直接判断最大空闲分区是否满足要求。
4) 内存回收
根据释放区首址和大小,查找空闲分区表/链表,判断是否有相邻的空闲分区存在:
 释放区与前空闲区相邻:将释放区与前空闲区合并为一个空闲区。其首址仍为前空闲区首址,大小为释放区大小与空闲区大小之和。
 释放区与前后两个空闲区相邻:将这三个区合为一个空闲区,其首址为前空闲区首址,大小为这三个区大小之和,并取消原后空闲区表目。
 释放区与后空闲区相邻:则把释放区合并到后空闲,首地址为释放区首地址,大小为二者大小之和。
 释放区不与任何空闲区相邻:将释放区作为一个空闲区,将其大小和首址插入到空闲区表的适当位置。

实验目的或要求:通过本实验使我们深入理解计算机存储器管理的连续分配方式或离散分配方式的分页技术的思想与实现方法,使我们更好分析和掌握连续或分页实现内存管理的特点,达到对计算机学科基础实践能力、问题分析、设计、算法实现的专业核心能力的培养。
开发一个C语言程序实现内存空间管理的动态分区分配方案。根据进程的实际需要,动态地创建分区为之分配内存空间,在实现动态分区分配时,将涉及分区分配中所使用的数据结构,分区分配算法和分区的分配与回收操作等问题。设计分区分配中的数据结构,实现内存分配过程,使用首次适应法实现分配内存空间作用,并处理好各种内存回收中的各种情况,比如释放区与前空闲区相邻,释放区与前后两个空闲区相邻等等。

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>

int memory = 0; //存储空间的大小
int count = 0;	//记录总的作业数
typedef struct Storage{
	int number;		//作业号
	int start;
	int last;
	int size;
	int state;	//区分内存空间是已分配还是未分配  空闲为0 
	struct  Storage *next;
}Storage;
int add(Storage *head,int number,int size){
	Storage *add1 = head->next;
	//遍历
	while(add1 != NULL){
		//找到大于或等于插入作业的空闲区 
		if(add1->number==-1 && add1->size>=size){
			break; 
		}
		add1 = add1->next;
	}
	if(add1 == NULL){
		//未找到合适的空闲区
		return 0;	
	}
	//将空闲区划分为两个部分
	int sizeOld = add1->size;
	
	//存储作业 
	add1->number=number;
	add1->size = size;
	add1->state = 1;
	add1->last = add1->start + size - 1;

	//新空闲区部分
	Storage *add2 = (Storage *)malloc(sizeof(Storage));
	add2->number = -1;
	add2->size = sizeOld - size;
	add2->start = add1->last + 1;
	if(add2->start >= memory - 1){
		add1->next = NULL;
		return 1; 
	} 
	add2->state = 0;
	add2->last = add2->start + add2->size - 1;
	add2->next = add1->next;
	add1->next = add2;	
	return 1; 
}

int deleted(Storage *head,int id){
	Storage *del1 = head->next;
	Storage *del2 = del1->next;
	int temp1 = -1,temp2 = -1;
	
	while(del1 != NULL){
		if(id == del2->number){
			temp1 = 0;
			temp2 = 0; 
			//与前一个空闲区相邻 
			if(del1->state == 0){
				temp1 = 1;
			}
			//与后一个空闲区相邻 
			if(del2->next->state == 0){
				temp2 = 1;
			}
			break;
		}
		del1 = del1->next;
		del2 = del2->next;
	}
	//讨论空闲区前后空闲区情况 
	//前后都是空闲区
	if(temp1 == 1 && temp2 == 1){ 
		del1->last = del2->next->last;
		del1->size = del1->size + del2->size + del2->next->size;
		del1->state = 0;	
		del1->number = -1; 
		del1->next = del2->next->next;
	}
	//前面是空闲区 
	else if(temp1 == 1){
		del1->number = -1;
		del1->size = del1->size + del2->size;
		del1->state = 0;
		del1->last = del2->last;
		del1->next = del2->next;
	}
	//后面是空闲区 
	else if(temp2 == 1){ 
		del2->number = -1;
		del2->size = del2->size + del2->next->size;
		del2->state = 0;
		del2->last = del2->next->last;
		del2->next = del2->next->next; 
	}
	//前后都不是空闲区
	else{
		del2->number = -1;
		del2->state = 0;
	} 
	return 1;
}
//查看内存分配情况 
void viewinformation(Storage *head){
	Storage *p = head->next;
	while(p != NULL){
		if(0 == p->state){
			printf("空闲区  \tstart = %d\tlast = %d\tsize = %d\n",p->start,p->last,p->size);
		} 
		else{
			printf("作业id = %d\tstart = %d\tlast = %d\tsize = %d\n",p->number,p->start,p->last,p->size);
		}
		p = p->next;
	}
}

void firstview(){
	    printf("1: 为新作业分配内存\n");
        printf("2: 回收作业释放内存\n");
 	    printf("3: 查看内存分配情况\n");        
		printf("4:退出\n");
		printf( "请输入操作: " );
} 
int main(){
	printf("请输入存储空间大小(单位K):");
	scanf("%d",&memory);
	//初始化 
	Storage *head = (Storage *)malloc(sizeof(Storage));
	Storage *storage = (Storage *)malloc(sizeof(Storage));
	head->next = NULL;
	storage->number = -1;
	storage->size = memory;
	storage->start = 0;
	storage->last = memory-1;
	storage->state = 0;
	storage->next = NULL;
	head->next = storage;
	while(1){
		int chioce, id, size;
		firstview();
        scanf("%d", &chioce);
        switch(chioce){
        	//四个选项,分别做不同的事情 
			case 1 : {
				//分配新作业 
        		printf("请输入作业id 和 作业大小size:\n");
        		printf("id = ");
        		scanf("%d",&id);
        		printf("size = ");
        		scanf("%d",&size);
        		if(add(head,id,size)){ 
					printf("空间分配成功!\n");
					//每分配一次空间,作业数加一 
					count++; 
				} 
				else{
					printf("空间分配失败!\n");
				}
				break;
			} 
			case 2 : {
				//回收作业 
				printf("请输入回收作业的 id:");
				scanf("%d",&id);
				if(deleted(head,id)){
					//回收成功 
					count--;
					printf("作业回收成功!\n");	
				}
				else{
					//回收失败 
					printf("作业回收失败!\n");
				}
				break;
			}
			case 3 : { 
				//查看分配情况 
				viewinformation(head);
				break;
			} 
			case 4 : {
				//退出程序 
				return 0;
			} 
		}
	}
	return 0;
}

  • 23
    点赞
  • 94
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
实验内容: 编写一个动态分区分配算法模拟程序,加深对动态分区存储管理方式及其实现过程的理解。 要求: 1.空闲分区通过空闲区链进行管理,在内存分配时,优先考虑低地址部分的空闲区。 2.分别采用首次适应算法、最佳适应算法和最坏适应算法模拟内存空间的动态分配与回收,每次分配和回收后显示出空闲区链的详细情况(说明:在申请不成功时,需要打印当前内存的占用情况信息)。 3.进程对内存空间的申请和释放可由用户自定义输入。 4.参考请求序列如下: (1) 初始状态下可用内存空间为640KB; (2) 进程1申请130KB; (3) 进程2申请60KB; (4) 进程3申请100KB; (5) 进程2释放60KB; (6) 进程4申请200KB; (7) 进程3释放100KB; (8) 进程1释放130KB; (9) 进程5申请140KB; (10) 进程6申请60KB; (11) 进程7申请50KB; (12) 进程6释放60KB。 测试用例格式如下: 输入: 动态分区分配算法选择 可用内存空间容量 序号/进程号/申请或释放操作/申请或释放的容量 其: (1) 动态分区分配算法:1----首次适应,2----最佳适应,3----最坏适应 (2) 申请或释放操作: 1----申请操作,2----释放操作 输出: 序号/内存空间状态1/内存空间状态2...... 内存空间状态表示分为两种情况: (1) 内存空间被占用: 内存空间起始地址-内存空间结束地址.1.占用的进程号 (2) 内存空间空闲 内存空间起始地址-内存空间结束地址.0
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值