#include <bits/stdc++.h>
using namespace std;
#define maxsize 1e3
#define emp 0
#define use 1
typedef struct freespace
{
int address;//空闲分区的首地址
int size;//空闲分区的长度
int state;//空闲分区的状态
}free_table;//空闲分区表,用一维数组或者双向链表实现
// 线性表的双向链表存储结构
typedef struct Lnode
{
free_table data;
Lnode *prior;
Lnode *nex;
} DLnode;
typedef DLnode* Dlinklist;
Dlinklist Lhead;//头结点代表系统占用内存
Dlinklist Ltail;//尾结点代表用户区
Dlinklist prenode;
Dlinklist inchead;
Dlinklist dechead;
bool init();//初始化内存
bool alloc();//分配内存
bool Free();//释放内存
void lmalloc(int, int, int);//分配内存
bool NF(int);//循环首次适应
bool BF(int);//最佳适应
bool WF(int);//最坏适应
void show();//显示内存使用情况
void view(Dlinklist&);
void outmenu();//显示菜单
void INC(Dlinklist&);//上升排序
void DEC(Dlinklist&);//下降排序
int choose;//选择使用的算法
int main()
{
puts("请输入要使用的算法");
outmenu();
scanf("%d", &choose);
init();
while (1)
{
puts("请输入要进行的操作:\n1.表示要申请内存\n2.表示要释放的内存\n3.表示要显示现在内存使用情况\n4.表示退出\n");
int op;
scanf("%d", &op);
if(op==4) break;
else if(op==1) alloc();
else if(op==2) Free();
else if(op==3) show();
}
puts("成功退出");
}
bool init()
{
// puts("你现在正在调用init");
Lhead = (Dlinklist)malloc(sizeof(DLnode));
Ltail = (Dlinklist)malloc(sizeof(DLnode));
inchead = (DLnode*)malloc(sizeof(DLnode));
inchead->nex = NULL;
dechead = (DLnode*)malloc(sizeof(DLnode));
dechead->nex = NULL;
if(Lhead!=NULL)//申请内存成功
{
//这一部分是模拟系统占用内存
Lhead->data.address = 0;
Lhead->data.size = 100;
Lhead->data.state = use;
Ltail -> data.address = 100;//尾结点的地址是100
Ltail -> data.size = maxsize-100;//分区大小最大是maxsize
Ltail -> data.state = emp;//状态是空
prenode = Lhead;//初始时是从首结点的下一个结点开始
Lhead -> prior = NULL;//头节点的前驱节点指向空
Lhead -> nex = Ltail;//头节点的后继指向尾结点
Ltail -> prior = Lhead;//尾结点的前驱指针指向头节点
Ltail -> nex = NULL;//尾结点下后继指针为空
// cout<<Lhead->data.address<<" "<<Lhead->data.size<<endl;
// cout<<Lhead->nex->data.address<<" "<<Lhead->nex->data.size<<endl;
// cout<<prenode->data.address<<" "<<prenode->data.size<<endl;
return true;
}else return false;
}
bool alloc()
{
int need;
printf("请输入所需内存的大小\n");
scanf("%d", &need);
while(need<=0){
printf("请重新输入\n");
scanf("%d", &need);
}
bool flag = false;
switch (choose)
{
case 1:
flag = NF(need);
break;
case 2:
flag = BF(need);
break;
case 3:
flag = WF(need);
break;
default:
break;
}
return flag;
}
bool Free()
{
puts("请输入要释放的内存的首地址,和大小");
int addr, large;
scanf("%d %d", &addr, &large);
Lnode *p = Lhead->nex;
while (p!=NULL)
{
if(p->data.address==addr&&p->data.size==large&&p->data.state==use){
break;
}
p = p->nex;
}
p->data.state = emp;//置为空闲状态
//与前面那个区块合并
if(p!=Lhead && p->prior!=Lhead && p->prior->data.state == emp)
{
p->prior->data.size += p->data.size;
p->prior->nex = p->nex;
p->nex->prior = p->prior;
Dlinklist temp = p;
p = p->prior;
free(temp);
}
//与后面那个区块合并
if(p!=Ltail && p->nex!=Ltail && p->nex->data.state == emp)
{
Dlinklist temp = p->nex;
p->data.size += p->nex->data.size;
p->nex->nex->prior = p;
p->nex = p->nex->nex;
free(temp);
}
//如果后方区块是最后一个块
if(p->nex==Ltail && p->nex->data.state == emp)
{
Dlinklist temp = p->nex;
p->data.size += p->nex->data.size;
free(temp);
p->nex = NULL;
}
return true;
}
bool NF(int need)
{
puts("你现在在调用NF");
DLnode *p = prenode->nex;
cout<<p->data.address<<" "<<p->data.size<<" "<<p->data.state<<endl;
while (p)
{
//查询现有的空闲分区中有没足够的大小
if(p->data.state == emp && p->data.size==need)//相等的情况
{
p->data.state = use;//大小相等,不需要分裂,直接修改状态位
prenode = p;//循环首次适应,每次都要记录一下上次是在哪里匹配到的
return true;
}
if(p->data.state == emp && p->data.size>need)//不相等的情况
{
cout<<"YYYY"<<endl;
Dlinklist temp = (Dlinklist)malloc(sizeof(DLnode));
temp->data.size = need;//设置新空间的大小
temp->data.state = use;//新空间的状态应该为已分配
temp->data.address = p->data.address;
temp->prior = p->prior;
temp->nex = p;
p->prior->nex = temp;
p->prior = temp;
p->data.address += need;//修改剩余空间的首地址
p->data.size -= need;//修改剩余空间的大小
prenode = temp;
return true;
}
p = p->nex;
}
p = Lhead->nex;//如果在上面那次循环中没有找到的话,那么要从头开始再找一次
while (p)
{
//查询现有的空闲分区中有没足够的大小
if(p->data.state == emp && p->data.size==need)//相等的情况
{
p->data.state = use;//大小相等,不需要分裂,直接修改状态位
prenode = p;//循环首次适应,每次都要记录一下上次是在哪里匹配到的
return true;
}
if(p->data.state == emp && p->data.size>need)//不相等的情况
{
Dlinklist temp = (Dlinklist)malloc(sizeof(DLnode));
temp->data.size = need;//设置新空间的大小
temp->data.state = use;//新空间的状态应该为已分配
temp->prior = p->prior;
temp->nex = p;
temp->data.address = p->data.address;
p->prior->nex = temp;
p->prior = temp;
p->data.address += need;//修改剩余空间的首地址
p->data.size -= need;//修改剩余空间的大小
prenode = temp;
return true;
}
p = p->nex;
}
return false;//如果都没有的话说明已经没有足够大的完整的块可以放下的返回失败
}
bool BF(int need)
{
puts("你现在在调用BF");
INC(inchead);
view(inchead);
bool flag = false;
DLnode *p = inchead->nex;
DLnode temp;
while (p)
{
if(p->data.size>=need){
temp.data.address = p->data.address;
temp.data.size = p->data.size;
temp.data.state = use;
flag = true;
break;
}
p = p->nex;
}
if(!flag) return flag;
lmalloc(temp.data.address, temp.data.size, need);
return flag;
}
bool WF(int need){
puts("你现在在调用WF");
DEC(dechead);
puts("decyes");
bool flag = false;
Lnode *p = dechead->nex;
Lnode *temp = (Dlinklist)malloc(sizeof(DLnode));
while (p)
{
if(p->data.size>=need){
temp->data.address = p->data.address;
temp->data.size = p->data.size;
temp->data.state = use;
flag = true;
break;
}
p = p->nex;
}
lmalloc(temp->data.address, temp->data.size, need);
return flag;
}
void lmalloc(int addr, int large, int need){
DLnode *p = Lhead->nex;
puts("now you are using lmalloc");
while (p)
{
if(p->data.address==addr && p->data.size==large && p->data.state==emp){
if(p->data.size==need) p->data.state = use;
else{
Dlinklist temp = (Dlinklist)malloc(sizeof(DLnode));
temp->data.size = need;//设置新空间的大小
temp->data.state = use;//新空间的状态应该为已分配
temp->data.address = p->data.address;
temp->prior = p->prior;
temp->nex = p;
p->prior->nex = temp;
p->prior = temp;
p->data.address += need;//修改剩余空间的首地址
p->data.size -= need;//修改剩余空间的大小
}
break;
}
p = p->nex;
}
puts("succsse lmalloc");
}
void show(){
puts("内存使用情况");
Lnode *p = Lhead;
puts("首地址 长度 是否被占用");
while (p)
{
printf(" %d %d %d\n", p->data.address, p->data.size, p->data.state);
p = p->nex;
}
}
void INC(Dlinklist &a){
puts("你现在在调用INC");
while (a!=NULL)
{
Dlinklist temp = a->nex;
free(a);
a = temp;
}
a = NULL;
a = (Dlinklist) malloc(sizeof(DLnode));
a->nex = NULL;
Lnode *p = Lhead->nex;
Lnode *t = a;
while (p)
{
if(p->data.state == use){
p = p->nex;
continue;
}
if(t->nex == NULL){
Lnode *temp = (Dlinklist)malloc(sizeof(DLnode));
temp->data = p->data;
t->nex = temp;
temp->prior = t;
temp->nex = NULL;
}
else{
while (t->nex)
{
if(p->data.size>=t->nex->data.size) t = t->nex;
else break;
}
if(t->nex==NULL){
Lnode *temp = (Dlinklist)malloc(sizeof(DLnode));
temp->data = p->data;
t->nex = temp;
temp->prior = t;
temp->nex = NULL;
}
else{
Lnode *temp = (Dlinklist)malloc(sizeof(DLnode));
temp->data = p->data;
temp->nex = t->nex;
t->nex->prior = temp;
t->nex = temp;
temp->prior = t;
}
t = a;//回到头节点为下一次插入做准备
}
p = p->nex;
}
}
void DEC(Dlinklist &a){
puts("你现在在调用DEC");
while (a!=NULL)
{
Dlinklist temp = a->nex;
free(a);
a = temp;
}
a = NULL;
a = (Dlinklist) malloc(sizeof(DLnode));
a->nex = NULL;
Lnode *p = Lhead->nex;
Lnode *t = a;
while (p)
{
if(p->data.state == use){
p = p->nex;
continue;
}
if(t->nex == NULL){
Lnode *temp = (Dlinklist)malloc(sizeof(DLnode));
temp->data = p->data;
t->nex = temp;
temp->prior = t;
temp->nex = NULL;
}
else{
while (t->nex)
{
if(p->data.size<=t->data.size) t = t->nex;
else break;
}
if(t->nex==NULL){
Lnode *temp = (Dlinklist)malloc(sizeof(DLnode));
temp->data = p->data;
t->nex = temp;
temp->prior = t;
temp->nex = NULL;
}
else{
Lnode *temp = (Dlinklist)malloc(sizeof(DLnode));
temp->data = p->data;
temp->nex = t->nex;
t->nex->prior = temp;
t->nex = temp;
temp->prior = t;
}
t = a;//回到头节点为下一次插入做准备
}
p = p->nex;
}
}
void view(Dlinklist &a){
Lnode *p = a;
p = p->nex;
while (p)
{
printf(" %d %d %d\n", p->data.address, p->data.size, p->data.state);
p = p->nex;
}
}
void outmenu(){
puts("1.NF循环首次适应算法\n2.BF最佳适应算法\n3.WF最坏适应算法\n");
}
实验1 可变分区存储管理
于 2022-06-14 16:46:01 首次发布