BF算法、男朋友算法,哈哈
要实现动态分区分配,需要考虑三个方面的问题。分别是数据结构、分区分配算法、分区的分配与回收操作。
首数据结构
这里我们使用的是空闲分区链,采用双向链表表示空闲分区。
具体实现如下:
typedef struct LNode{
int order; //表示内存块的顺序
int start; //表示内存的初始地址
int end; //表示内存的结束地址
int size; //表示内存块的大小
int state; //表示内存块的状态,1表示被占用,0表示空闲
int process; //存储占用该内存块的进程的序号
struct LNode *next; //指向下一个内存块
struct LNode *pre; //指向上一个内存块
}LNode;
分配算法
采用基于顺序搜索的动态分区分配算法中的最佳适应(best fit BF)算法。
每次为作业分配内存时,总是把能满足要求,又是最小的空闲分区分配给作业,避免“大材小用”。
内存的分配与回收
- 分配内存
从空闲分区链中找到所需大小的分区。设请求的分区大小为u.size,表中每个空闲分区的大小可表示为m.size,若m.size-u.size>=0时进行内存分配操作,若大于0,则申请一新节点,插入到双向链表中,若等于0,则只需修改符合要求的结点的信息就行了。 - 回收内存,四种情况(F:要回收的内存区、F1:F的前一分区、F2:F的后一分区)
- F与F1地址衔接,且F1空闲,将F与F1合并,合并后结点首地址为F1首地址,末地址为F末地址,结点数减一。
- F与F2地址衔接,且F2空闲,将F与F2合并,合并后结点首地址为F首地址,末地址为F2末地址地址,结点数减一。
- F与F1和F2的地址衔接,且F1,F2空闲,合并后结点首地址为F1首地址,末地址为F2末地址,结点数减二。
- 其他情况,将结点的state标志和process标志均设置为0。
程序解释
int buf[N]={100,500,200,700,300}; //内存块大小,用来初始化空闲分区链表
int add[N]={20,150,700,950,1700,}; //内存块的初始地址,用来初始化空闲分区链表
int dis[N]={301,400,310,105,190}; //进程所需内存,下标记为进程编号
List list_init(); //用来初始化空闲分区链表的函数,返回空闲分区链表的头部
void print(List head); //顺序输出链表的信息
List allot_memory(List head,ing i);//为编号为i的进程分配内存
List free_memory(List head,int i);//释放编号为i的进程所占用的内存
全部代码
#include<stdio.h>
#include<stdlib.h>
#define N 5
int buf[N]={100,500,200,700,300};
int add[N]={20,150,700,950,1700,};
int dis[N]={301,400,310,105,190};
typedef struct LNode *List;
typedef struct LNode{
int order;
int start;
int end;
int size;
int state;
int process;
struct LNode *next;
struct LNode *pre;
}LNode;
List list_init(){
List head,p,m;
int i;
for(i=0;i<N;i++){
m=(List)malloc(sizeof(struct LNode));
if(!m){
printf("error\n");
exit(0);
}
m->order=i+1;
m->start=add[i];
m->end=m->start+buf[i]-1;
m->size=buf[i];
m->next=NULL;
m->pre=NULL;
m->state=0;
p->process=0;
if(i==0)
head=p=m;
else{
p->next=m;
m->pre=p;
p=p->next;
}
}
return head;
}
void print(List head){
List p=head;
while(p){
printf("第%d块内存--->始地址:%-5d--->末地址:%-5d--->大小:%-5d--->状态:",p->order,p->start,p->end,p->size);
if(p->state==1)
printf("被%d号进程占用中!\n",p->process);
else if(p->state==0){
printf("空闲中!\n");
}
p=p->next;
}
printf("\n");
}
List free_memory(List head,int i){
List p,m,temp;
p=head;
while(p){
if(p->process==i+1){
temp=p;
if(p->next){
m=p->next;
if(p->end+1==m->start){
if(!m->state){
p->size+=m->size;
p->end+=m->size;
p->next=m->next;
p->state=0;
p->process=0;
if(m->next){
m->next->pre=p;
}
p=m->next;
free(m);
while(p){
p->order--;
p=p->next;
}
}
else{
p->state=0;
p->process=0;
}
}
else{
p->state=0;
p->process=0;
}
}
p=temp;
if(p->pre){
m=p->pre;
if(p->start==m->end+1){
if(!m->state){
m->size+=p->size;
m->end+=p->size;
m->next=p->next;
if(p->next){
p->next->pre=m;
}
free(p);
p=m->next;
while(p){
p->order--;
p=p->next;
}
}
else{
p->state=0;
p->process=0;
}
}
else{
p->state=0;
p->process=0;
}
}
return head;
}
p=p->next;
}
}
List allot_memory(List head,int i){
int memory_size=dis[i];
List p=head;
List m;
int min=-1;
int order=-1;
while(p){
if(p->process-1==i){
printf("内存中已有%d号进程了\n",i+1);
return head;
}
p=p->next;
}
p=head;
while(p){
if(p->size>=memory_size&&p->state==0){
if(min<0){
min=p->size-memory_size;
order=p->order;
}
else{
if(min>p->size-memory_size){
min=p->size-memory_size;
order=p->order;
}
}
}
p=p->next;
}
if(order==-1){
printf("%d号进程分配内存失败!\n",i+1);
return head;
}
else{
p=head;
while(p){
if(p->order==order){
if(p->size==memory_size){
p->state=1;
p->process=i+1;
return head;
}
else{
m=(List)malloc(sizeof(struct LNode));
m->order=p->order;
m->start=p->start;
m->end=m->start+memory_size-1;
m->size=memory_size;
m->state=1;
m->next=p;
m->process=i+1;
m->pre=p->pre;
p->pre->next=m;
p->pre=m;
p->start=m->end+1;
p->size-=memory_size;
while(p){
p->order++;
p=p->next;
}
return head;
}
}
p=p->next;
}
}
}
int main(){
List p,m;
int choice1,choice2;
int i;
p=list_init();
print(p);
p=allot_memory(p,3);
print(p);
p=allot_memory(p,3);
p=free_memory(p,3);
print(p);
p=allot_memory(p,0);
print(p);
p=allot_memory(p,4);
print(p);
p=free_memory(p,4);
print(p);
p=allot_memory(p,4);
print(p);
p=free_memory(p,0);
print(p);
p=free_memory(p,4);
print(p);
return 0;
}