#include <iostream>
#include <list>
using namespace std;
#define TOTLE_LEFT 108 //除系统占用内存外的剩余内存
#define frist_free 14 //第一块空闲区的起至地址
#define first_size 12 //第一块空闲区的大小
#define sec_free 32 //第二块空闲区的起至地址
#define sec_size 96 //第二块空闲区的大小
#define first_job_size 3
#define sec_job_size 23
#define third_job_size 3
//空闲分区表节点
struct Free
{
int start;
int length;
Free(int s,int l);
};
Free::Free(int s,int l)
{
start = s;
length = l;
}
//已分配分区表节点
struct Task
{
int name;
int start;
int length;
Task(int n,int s,int l);
};
Task::Task(int n,int s,int l)
{
name = n;
start = s;
length = l;
}
//声明空闲分区表
list<Free *> free_list;
list<Task *> task_list;
//分配可用起始地址
int get_free(int size)
{
int start = -1;
//查找适当的空闲分区
list<Free *>::iterator it=free_list.begin();
bool find = false;
while(it!=free_list.end())
{
if((*it)->length>=size)
{
find=true;
start = (*it)->start;
//大于就分割把低地址分配出去
if((*it)->length>size)
{
(*it)->start += size;
(*it)->length -= size;
}
//等于就从空闲分区中删掉
else
free_list.erase(it);
break;//找到就跳出循环
}
it++;
}
return start;
}
void do_request(int name,int size)
{
if(name==0)
{
cout << "申请不合法!非法作业名!" << endl;
return;
}
if(size>TOTLE_LEFT)
{
cout << "申请不合法!超出最大可用内存!" << endl;
return;
}
//查找是否已存在同名作业
bool find = false;
list<Task *>::iterator it=task_list.begin();
while(it!=task_list.end())
{
if((*it)->name==name)
{
find=true;
break;
}
it++;
}
if(find)
{
cout << "此作业已存在!" << endl;
return;
}
//从空闲分区选择合适的空间
int start=get_free(size);
//未找到合适空间
if(start==-1)
{
cout << "系统内存不足!作业等待!" << endl;
return;
}
Task *ta = new Task(name,start,size);
task_list.push_back(ta);
cout << "作业申请内存成功!" << endl;
}
//插入到空闲分区表,按照起始地址从小到大
void free_task(int start,int length)
{
//查找要插入的位置
list<Free *>::iterator init_it,last_it;
last_it = init_it;
list<Free *>::iterator it=free_list.begin();
while(it!=free_list.end())
{
if((*it)->start > start) break;
last_it = it;
it++;
}
bool link_prev=false;
bool link_next=false;
//有前一个时
if(last_it!= init_it)
{
if((*last_it)->start+(*last_it)->length == start)
link_prev = true;
}
//有后一个时
if(it!=free_list.end())
{
if(start+length==(*it)->start)
link_next = true;
}
//与前后都相连
if(link_prev && link_next)
{
(*last_it)->length += length + (*it)->length;
free_list.erase(it);
}
//只与前相连
else if(link_prev)
{
(*last_it)->length += length;
}
//只与后相连
else if(link_next)
{
(*it)->start = start;
(*it)->length += length;
}
//前后都不相连
else
{
Free *fr = new Free(start,length);
free_list.insert(it,fr);
}
}
void do_revoke(int name)
{
if(name==0)
{
cout << "错误!不能回收系统内存!" << endl;
return;
}
//查找要回收的作业是否存在
bool find = false;
list<Task *>::iterator it=task_list.begin();
while(it!=task_list.end())
{
if((*it)->name==name)
{
find=true;
break;
}
it++;
}
if(!find)
{
cout << "错误!要回收的作业不存在!" << endl;;
return;
}
free_task((*it)->start,(*it)->length);
task_list.erase(it);
cout << "回收作业占用内存成功!" << endl;
}
void print_task()
{
cout <<"作业名称 起始地址 大小" << endl;
for(list<Task *>::iterator it=task_list.begin();it!=task_list.end();it++)
{
cout << (*it)->name <<" "
<< (*it)->start <<" "
<< (*it)->length << endl;
}
}
void print_free()
{
cout <<"以下是空闲分区表的状态"<< endl
<<"起始地址 大小" << endl;
for(list<Free *>::iterator it=free_list.begin();it!=free_list.end();it++)
{
cout << (*it)->start << " "
<< (*it)->length << endl;
}
}
int main()
{
//把系统占用后剩余的内存空间计入空闲分区表
Free *fr1 = new Free(frist_free,first_size);
free_list.push_back(fr1);
Free *fr = new Free(sec_free,sec_size);
free_list.push_back(fr);
Task *ta = new Task(1,26,first_job_size);
task_list.push_back(ta);
Task *ta1 = new Task(3,29,third_job_size);
task_list.push_back(ta1);
Task *ta2 = new Task(2,128,sec_job_size);
task_list.push_back(ta2);
print_free();
bool quit=false;
while(!quit)
{
cout <<"选择要进行的操作:1.申请内存 2.回收内存 3.查看作业>";
int op;
cin >> op;
if(op==1)
{
int name;
int size;
cout << "请输入作业名及占用空间大小(用空格隔开):";
cin >> name;
cin >> size;
do_request(name,size);
print_free();
}
else if(op==2)
{ int name;
cout << "请输入要回收的作业名:";
cin >> name;
do_revoke(name);
print_free();
}
else if(op==3)
{
print_task();
}
else
{
cout << "非法操作!" << endl;
}
cout << "******************************" << endl;
char con;
cout << "继续(y/n):";
cin >> con;
if(con=='n' || con=='N')
{
quit=true;
}
}
return 0;
}