可变分区下管理方式下的优先适应算法
#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;
}