操作系统---存储器空间的分配和回收实现

可变分区下管理方式下的优先适应算法

#define _CRT_SECURE_NO_WARNINGS

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

struct Table* init();//初始化
void increaseroom(struct Table* table);//表格空间扩容
void post_remove(int index, struct Table* table);//表格元素后移
void inorder_remove(int start, int end, struct Table* table);//表格元素前移
void printtable(struct Table* table);//输出内存信息
void add(struct Table* table);//申请内存空间
void rollback(struct Table* table);//空间回收
void roomadd(struct Table* table);未分配的休闲区合并
void freeroom(struct Table* table);回收动态开辟的空间


struct Table {
	int line;//表占用的行数
	int capacity;//表的最大容量
	struct  Information* info;//每一行表格的信息
};
struct Information {
	int   id;
	char name;
	int address;
	int length;
	char* status;
};
struct Table* init() {
	printf("初始化内存空间,输入初始化内存大小\n");
	int n;
	scanf("%d", &n);
	struct Table* table = (struct Table*)malloc(sizeof(struct Table));
	if (table == NULL) {
		printf("申请空间失败,程序结束\n");
		exit(-1);
	}
	table->capacity = 1;
	struct Information* info = (struct Information*)malloc(sizeof(struct Information) * table->capacity);
	table->line = 1;
	table->info = info;
	//动态申请空间,table指向结构体类型的数组
	if (info == NULL) {
		printf("申请空间失败,程序结束\n");
		exit(-1);
	}
	info[0].id = 1;
	info[0].name = 'P';
	info[0].status = (char*)calloc(sizeof(char) * 10, '0');
	if (info[0].status == NULL) {
		printf("申请空间失败,程序结束\n");
		exit(-1);
	}
	info[0].length = n;
	info[0].address = 0;
	strcpy(info[0].status, "未分配");
	return table;
}
//表格扩容
void increaseroom(struct Table* table) {
	if (table->line >= table->capacity) {//需要进行扩容
		table->capacity *= 2;
		table->info = (struct Information*)realloc(table->info, sizeof(struct Information) * table->capacity);
	}
	if (table->info == NULL) {
		printf("申请空间失败,程序结束\n");
		exit(-1);
	}
}
//元素后移
void post_remove(int index, struct Table* table) {
	for (int i = table->line - 1; i > index; i--) {
		table->info[i].id = table->info[i - 1].id + 1;//增加一个之后序号增加
		table->info[i].length = table->info[i - 1].length;
		table->info[i].address = table->info[i - 1].address;
		table->info[i].name = table->info[i - 1].name;
		strcpy(table->info[i].status, table->info[i - 1].status);
	}
}
//元素前移
void inorder_remove(int start, int end, struct Table* table) {
	int pos = end - start;//2-0=2;
	table->line -= pos;
	for (int i = start + 1; i < table->line; i++) {
		table->info[i].length = table->info[i + pos].length;
		table->info[i].address = table->info[i + pos].address;
		table->info[i].name = table->info[i + pos].name;
		strcpy(table->info[i].status, table->info[i + pos].status);
	}
}

//输出内存信息
void printtable(struct Table* table) {
	printf("内存状况如下\n");
	for (int i = 0; i < table->line; i++) {
		printf("行号: %6d  作业名称:  %6c  起始地址: %6d  空间大小: %6d  状态: %6s\n", table->info[i].id, table->info[i].name, table->info[i].address, table->info[i].length, table->info[i].status);
	}
}
//申请内存空间
void add(struct Table* table) {
	printf("输入作业名称和申请空间的大小\n");
	int size;
	char ch = '\n';
	while (ch == '\n') {
		ch = getchar();
	}
	scanf("%d", &size);
	int n = table->line;
	int flag = 0;
	for (int i = 0; i < n; i++) {
		if (table->info[i].length >= size && strcmp(table->info[i].status, "未分配") == 0) {//如果内存分区的空间足够且没有被分配
			//执行分配任务
			table->line++;//记录加1
			increaseroom(table);//扩容
			table->info[table->line - 1].status = (char*)calloc(sizeof(char) * 10, '0');
			if (table->info[i].length != size) {
				post_remove(i + 1, table);//元素后移
			}

			strncpy(table->info[i].status, "已分配", 6);
			table->info[i + 1].id = table->info[i].id + 1;
			table->info[i + 1].address = table->info[i].address + size;

			table->info[i + 1].length = table->info[i].length - size;
			table->info[i].length = size;
			table->info[i].name = ch;

			table->info[i+1].name = 'P';
			strncpy(table->info[i + 1].status, "未分配", 6);
			flag = 1;
			break;
		}
	}
	if (flag == 1) {
		printf("申请空间成功\n");
		
		printtable(table);
	}
	else {
		printf("申请空间不成功\n");
	}
}
//回收内存空间
/*作业所占的区域应该归还,归还的区域如果与其它空闲区相邻,则应合成一个较大的空闲区
*/

//未分配的休闲区合并
void roomadd(struct Table* table) {
	int flag = 0;
	int start = 0;
	int end = 0;
	for (int i = 0; i < table->line - 1; i++) {
		int j = i;
		int sum = table->info[i].length;
		while (j < table->line - 1 && (strcmp(table->info[j].status, "未分配") == 0) && (strcmp(table->info[j + 1].status, "未分配") == 0)) {
			sum += table->info[j + 1].length;
			j++;
			flag = 1;//进行了空闲区合并
		}
		table->info[i].length = sum;
		if (flag == 1) {
			start = i;
			end = j;
			//合并之后,表格数据前移
			inorder_remove(start, end, table);
		}
	}
}
//空间回收
void rollback(struct Table* table) {
	printf("输入回收空间的作业的行号和回收空间大小\n");
	int i = 0;
	scanf("%d", &i);
	int size = 0;
	scanf("%d", &size);
	if (i >= 1 && i <= table->line) {
		if (strcmp(table->info[i - 1].status, "已分配") == 0) {
			if (size == table->info[i - 1].length) {
				strcpy(table->info[i - 1].status, "未分配");
				table->info[i - 1].name = 'P';

			}
			else if (size > table->info[i - 1].length) {
				printf("所释放的空间大于本身拥有的空间,释放失败\n");
				return;
			}
			else {
				printf("释放成功\n");
				table->info[i - 1].length -= size;
				strcpy(table->info[i - 1].status, "已分配");
				table->line++;//记录加1
				increaseroom(table);//扩容
				table->info[table->line - 1].status = (char*)calloc(sizeof(char) * 10, '0');
				post_remove(i, table);//元素后移
				table->info[i].id = table->info[i - 1].id + 1;
				table->info[i].name = 'P';
				table->info[i].address = table->info[i - 1].length;
				table->info[i].length = size;
				strcpy(table->info[i].status, "未分配");
			}

			roomadd(table);
			printtable(table);
		}
		else {
			printf("这个空间是没有分配的空间,不可以释放\n");
		}
	}
	else {
		printf("输入回收空间的序号不合法\n");
	}
}
//回收动态开辟的空间
void freeroom(struct Table* table) {
	for (int i = 0; i < table->line; i++) {
		free(table->info[i].status);//出错:内存的越界访问 申请空间比实际用到的空间少 传入/0
		//使用calloc申请status,这样可以初始化内容为'\0',防止空间初始化不彻底,还可以在其基础上使用strncpy函数
	}
	free(table->info);
	free(table);
}
void menu(struct Table* table) {
	printf("***********************\n");
	printf("********0->退出********\n");
	printf("********1->申请********\n");
	printf("********2->释放********\n");
	printf("***********************\n");
	while (1) {
		printf("请输入执行的操作:\n");
		int n = 0;
		scanf("%d", &n);
	
		switch (n) {
		case 0:
			printf("退出\n");
			freeroom(table);
			return;
		case 1:
			
			add(table);
			break;
		case 2:
			rollback(table);
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	}

}
int main() {
	struct Table* table = init();
	menu(table);
	return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值