动态分区分配

    关于动态分区分配,涉及两部分:分配内存和回收内存。

    对于分配内存,我们需要在内存分区中检索空闲分区。对检索到的空闲分区a与所需分区大小b比较,若空间不足够继续检索;否则,就对a和b之差是否小于size值。当差小于size值是将分区a直接分配,当差值大于size值,那么就在b分区划出a大小的分区。

    回收分区时,应考虑所回收分区的前后分区是否为空闲,空闲则合并。


typedef struct  node//动态分配

{
int id; //分区号
char name;       //作业名
int s; //分区大小
int startadd; //起始地址
int state; //状态
int end;
//struct node *next;
}elemtype; 
typedef struct
{
elemtype data[N];
int next;
}SequenList;
SequenList *L;


void init()//初始化
{
L=(SequenList *)malloc(sizeof(SequenList));
L->next=0;
L->data[0].name= '*';
L->data[0].state=0;
L->data[0].startadd=0;
L->data[0].end=1023;
L->data[0].s=1024;//大小
}


//插入
int insert_Sequen(elemtype x,int i)
{
//L是SequenList类型的指针变量,
//i是插入的位置,x是待插入结点的数据元素值
int j;
if(L->next >=  N-1)
{
printf("表满!数据溢出\n");
return 0;
}
if(i<0||i>L->next+2)
{
printf("非法位置\n");
return 0;
}
for(j=L->next;j>=i-1;j--)
{
L->data[j+1] = L->data[j];
}
L->data[i-1] = x;
L->next = L->next + 1;
return 1;
}


int delete_Sequen(int i)//删除结点
{
int j;
if(i<0||i>L->next+1)
{
printf("位置非法\n");
return 0;
}
else
{
for(j=i;j<=L->next;j++)
L->data[j-1] = L->data[j];
L->next--;
}
return 1;
}


//分配内存
void fenpei()
{
char name;//作业名
int u;//大小
int flag,i;
elemtype x;
printf("作业名(一个字符):");
scanf("%s",&name);
printf("作业大小:");
scanf("%d",&u);


for(i=0;i<=L->next;i++)
{
//printf("aaa\n");
if(L->data[i].s >= u&&L->data[i].state==0)//空间空闲并且空间大小大于需要的
{
if((L->data[i].s-u)<=size)//空间大小-需要的空间大小<4,直接分配
{
L->data[i].state = 1;
L->data[i].name = name;
flag=1;
printf("dd\n");
}
else//从分区中划出u
{
//把这个分区信息存入到下一个分区单元i+1,以此划分分区
x.name=L->data[i].name;
x.startadd=L->data[i].startadd;
x.s=u;
x.end=x.startadd+x.s;
x.state=L->data[i].state;
flag=insert_Sequen(x,i+1);//插入数据x

//新分区i名字状态
L->data[i].name=name;
L->data[i].state=1;


//划分后剩余分区起始地址和大小
L->data[i+1].startadd=L->data[i].startadd+u;
L->data[i+1].s=L->data[i+1].s-u;

//printf("i:i%d  name %c  state %d  startadd %d   end %d   s %d\n",i,L->data[i-1].name,L->data[i-1].state,L->data[i-1].startadd,L->data[i-1].end,L->data[i-1].s);
}
break;
}
}
if(flag == 0)
printf("分配失败\n");
else
printf("分配成功哈\n");
}


//回收内存
void huishou()
{
char name;
int i,flag;
printf("请输入回收分区的作业名(一个字符):");
scanf("%s",&name);


for(i=0;i<=L->next;i++)
{
if(L->data[i].name == name)
{
L->data[i].name == '*';//名字置为空
L->data[i].state = 0;//状态置为0


//回收:分情况
//回收区与插入点的前一个空闲分区F1相连接
if(L->data[i-1].state == 0 &&  L->data[i+1].state != 0)
{


L->data[i].startadd = L->data[i-1].startadd;
L->data[i].s = L->data[i].s + L->data[i-1].s;
L->data[i].end = L->data[i].startadd + L->data[i].s;


flag = delete_Sequen(i);//删除结点
L->data[i-1].name = '*';
break;
}
//回收分区与插入点的后一个空闲分区F2相连接
else if(L->data[i-1].state != 0 &&  L->data[i+1].state == 0)
{
L->data[i+1].startadd = L->data[i].startadd;
L->data[i+1].s = L->data[i+1].s + L->data[i].s;
L->data[i].end = L->data[i].startadd + L->data[i].s;
flag = delete_Sequen(i+1);//删除结点


L->data[i].name = '*';
printf("1  name %c\n",L->data[i].name);
break;
}
else if(L->data[i-1].state == 0 &&  L->data[i+1].state == 0)//回收区同时与插入点的前后两个分区相连
{
L->data[i].startadd = L->data[i-1].startadd;
L->data[i].s = L->data[i].s + L->data[i-1].s;
L->data[i].end = L->data[i].startadd + L->data[i].s;
flag = delete_Sequen(i);//删除结点


L->data[i-1].s = L->data[i-1].s + L->data[i+1].s;
L->data[i-1].end = L->data[i-1].startadd +L->data[i-1].s;
flag = delete_Sequen(i+1);
L->data[i-1].name = '*';
break;
}
 
else//都不空闲
{
flag = 1;
L->data[i].name = '*';
printf("3   name %c\n",L->data[i].name);
break;
}
}
}
if(flag == 0)
printf("回收失败!!\n");
else
printf("回收成功哈!!\n");
}

你可能感兴趣的:(内存)