模拟内存回收算法(C语言):
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
//#define NULL 0
typedef struct table
{
int address; /*存储分区起始地址*/
int length; /*存储分区长度*/
int flag; /*存储分区标志,0 为空闲,1 为被作业占据*/
char name[10]; /*当 flag==1 时存储分区占用标志作业名,否则存储空 nil*/
struct table *next;
} node;
node *work; /*设置一个全局变量 work:定位需要释放的结点*/
char type; /*设置一个全局变量 type:标注回收类型*/
bool success; /*设置一个全局变量 success:标注回收结点是否在分配分区表中*/
node *insert(node *head, node *p) /*按照“地址递增方式”将 p 结点插入链表相应位置*/
{
node *q=(node*)malloc(sizeof(node));
node *pre=(node*)malloc(sizeof(node));
q=head->next;
if(!q){ /*当head为空节点*/
head->next=p;
p->next=NULL;/*将next指向NULL很重要*/
return head;
}
pre=head;
while(q){
if(q->address > p->address){
pre->next=p;
p->next=q;
return head;
}
else{
pre=q;
q=q->next;
}
}
if(!q){ /*插入位置为末端时*/
pre->next=p;
p->next=NULL;
}
return head;
}
node *creat() /*根据地址递增方式建立分配分区表(flag==1)或空闲分区表(flag==0)*/
{
node *head=(node*)malloc(sizeof(node));
head->next=NULL;
node *p=(node*)malloc(sizeof(node));
printf("input:address,length,flag(0 or 1),name[10],当 length == -1 时结束:\n");
scanf("%d%d%d",&p->address,&p->length,&p->flag);
getchar();
scanf("%s",p->name);
while(p->length != -1){
head=insert(head,p);
p=(node*)malloc(sizeof(node));
//printf("input:address,length,flag(0 or 1),name[10],当 length == -1 时结束:\n");
scanf("%d%d%d",&p->address,&p->length,&p->flag);
getchar();
scanf("%s",p->name);
}
return head;
}
node *found(node *distributedhead,char workn[10]) /*查找已分配表中要回收的分区位置*/
{
int i;
int lens1=strlen(workn),lens2;
node *p=(node*)malloc(sizeof(node));
node *pre=(node*)malloc(sizeof(node));
p=distributedhead->next;
pre=distributedhead;
while(p){
lens2=strlen(p->name);
if(lens1!=lens2)
;
else{
for(i=0; i<lens1; i++){
if(p->name[i]!=workn[i])
break;
}
if(i == lens1){
success=true;
pre->next=p->next;
return p;
}
}
pre=p;
p=p->next;
}
success=false;
return NULL;
}
node *release(node *freehead,node *work) /*分四种情况完成空闲分区回收过程*/
{
node *p=(node*)malloc(sizeof(node));
node *q=(node*)malloc(sizeof(node));
p=freehead->next;
q=p->next;
/*D*/
if(work->address+work->length<p->address){
type = 'D';
work->flag=0;
work->name[0]='n';
work->name[1]='u';
work->name[2]='i';
work->name[3]='l';
for(int i=4;i<10;i++){
work->name[i]='\0';
}
freehead->next=work;
work->next=p;
return freehead;
}
while(q){
if(p->address+p->length < work->address && q->address > work->address+work->length ){
type='D';
p->next=work;
work->next=q;
return freehead;
}
p=p->next;
q=q->next;
}
if(!q){
if(p->address+p->length < work->address){
type='D';
p->next=work;
work->next=NULL;
return freehead;
}
}
/*C*/
p=freehead->next;
q=p->next;
while(q){
if(p->address+p->length == work->address && q->address == work->address+work->length ){
type='C';
p->length=p->length+work->length+q->length;
p->next=q->next;
return freehead;
}
p=p->next;
q=q->next;
}
/*A*/
p=freehead->next;
while(p){
if(p->address+p->length == work->address){
type='A';
p->length=p->length+work->length;
return freehead;
}
p=p->next;
}
/*B*/
p=freehead->next;
while(p){
if(p->address == work->address+work->length){
type='B';
p->address=work->address;
p->length=p->length+work->length;
return freehead;
}
p=p->next;
}
return freehead;
}
void print (node *head) /*输出链表*/
{
node *p=(node*)malloc(sizeof(node));
p=head->next;
while(p){
printf("%d,%d,%d,%s\n",p->address,p->length,p->flag,p->name);
p=p->next;
}
}
int main()
{
int i=1,sum;
struct table *dtable,*ftable;
char workn[10];
printf("The distributed table is:\n");
dtable=creat(); /*dtable 输入已分配情况表*/
printf("\nThe distributed table is:\n");
print(dtable);
printf("\n");
printf("The free table is:\n");
ftable=creat(); /*ftable 输入未分配情况表*/
printf("\nThe free table is:\n");
print(ftable);
printf("\n");
/*以下模拟逐个内存回收过程*/
printf("Input the released work segment sum:");
scanf("%d",&sum);
while(sum--){
printf("%d: input the released work segment name:",i++);
getchar();
scanf("%s",workn);
work = found(dtable,workn);
if(success){
printf("要回收的分区存在!\n");
ftable = release(ftable,work);
printf("The type of release is %c\n",type);
printf("The distributed table is:\n");
print(dtable);
printf("\n");
printf("The free table is:\n");
print(ftable);
printf("\n");
}
else{
printf("要回收的分区不存在!\n");
}
}
return 0;
}
测试用例:
/*0 60 1 OS
60 40 1 Task1
100 32 1 Task2
132 18 1 Task3
160 40 1 Task4
200 5 1 Task5
205 15 1 Task6
438 92 1 Task7
626 174 1 Task8
0 -1 0 0*/
/*150 10 0 nuil
220 218 0 nuil
530 96 0 nuil
0 -1 0 0*/
注:在写 insert 函数时,千万不要弄错 p ,q ,这两个很容易混掉 , 然后又很难找到这个bug,我之前可是在这上面耗了很长时间的,不过最后还是我的学霸室友发现的~