存储管理中的连续内存分配有绝对装入方式和可重定位装入方式。绝对装入方式,同一时间内存只能有一个进程在运行,程序在内存中的物理地址要和编写程序时的逻辑地址完全相同。可重定位装入方式,解决了多道程序设计的中多个程序装入内存的问题,实现了多个程序同时装入内存。动态分区分配算法有首次适应算法、循环首次适应算法、最佳适应算法、最坏适应算法。
首次适应算法:空闲分区链表以地址递增的次序连接,分配内存时从链首顺序查找,直到找到大小能够满足的空闲分区,缺点低地址不断被分割,产生很多很小的分区(碎片)。
循环首次适应算法:分配分区从上次找到的空闲分区的下一个空闲分区开始查找,减少碎片化及查找开销。
最佳适应算法:空闲分区按照分区大小从小到大排序,分配分区时总把能够满足需求并且是最小的空闲分区分配给作业,缺点容易产生碎片。
最坏适应算法:空闲分区按照分区大小从大到小排序,分配分区时选择最大的分配给作业,缺点每次都要分割大的空闲分区,这样会造成存储器缺少大的空闲分区。
动态分区分配之首次适应算法的C语言模拟:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct frist_fit { /*描述分区信息*/
int c_begin;
int c_size;
int NO;
struct frist_fit *next;
frist_fit() /*默认构造函数*/
{
c_begin = 0;
c_size = 0;
NO = -1;
next = NULL;
}
void set_date(int c_size,int c_begin = 0,int NO = -1) /*设置分区信息*/
{
this->c_size = c_size;
this->c_begin = c_begin;
this->NO = NO;
return;
}
};
int menu() /*菜单*/
{
printf("create pthread:1\n");
printf("free memory:2\n");
printf("if over input:0\n");
printf("plase input a num: ");
int m;
scanf("%d",&m);
switch(m){
case 0:
case 1:
case 2:
return m; break;
default:
return -1;
}
return m;
}
void init(struct frist_fit *head,int C_size) /*初始化空闲分区*/
{
struct frist_fit *temp = new frist_fit();
temp->set_date(C_size);
head->next = temp;
return;
}
void Out_one(struct frist_fit *t){ /*输出一个分区信息*/
printf("NO=%d,begin=%d,size=%d\n",t->NO,t->c_begin,t->c_size);
return;
}
void Out(struct frist_fit *head) /*输出所有分区信息*/
{
for(struct frist_fit *t = head ->next; t; t = t->next){
Out_one(t);
}
printf("\n");
}
void c_malloc(struct frist_fit *create,struct frist_fit *free) /*分配分区给作业*/
{
int NO,c_size;
printf("please input Pathread_NO and Memory\n");
scanf("%d%d",&NO,&c_size);
struct frist_fit *t = NULL;
for(t = create; t->next; t = t->next){ /*查找能够满足作业要求的空闲分区*/
if(t->next->c_size >= c_size){ /*能够满足要求*/
struct frist_fit *temp = new frist_fit();
temp->c_begin = t->next->c_begin;
temp->c_size = c_size;
temp->NO = NO;
temp ->next = free->next;
free->next = temp; /*已分配的分区加入到已分配分区链表*/
if(!(t->next->c_size - c_size)){ /*正好满足*/
struct frist_fit *p = t->next;
t->next = t->next->next;
delete p;
return;
}
else{ /*大于需求*/
t ->next->set_date(t->next->c_size - c_size,t->next->c_begin + c_size);
return;
}
}
}
if(t ->next == NULL){ /*没有能够满足需求的则返回*/
printf("malloc memory failed\n");
return;
}
return;
}
void c_free(struct frist_fit *create,struct frist_fit *free) /*收回分区*/
{
int NO;
printf("please input will delete pthread NO: ");
scanf("%d",&NO);
struct frist_fit *p = NULL;
struct frist_fit *pp = NULL;
for(p = free; p ->next; p = p->next) /*遍历已分配的分区*/
if(p->next->NO == NO){
pp = p->next;
p->next = p->next->next;
break;
}
if(!pp){ /*查找不到则返回*/
printf("the pthread not create\n");
return;
}
for(struct frist_fit *q = create ->next; q; q = q ->next){ /*遍历空闲分区*/
if(pp->c_begin + pp->c_size == q ->c_begin){ /*已分配分区与空闲分区相邻且在空闲分区的上方*/
q->set_date(q->c_size + pp->c_size,pp->c_begin,q->NO);
delete pp;
return;
}else if(q ->next && q ->next->c_begin + q->next->c_size == pp->c_begin){ /*已分配分区与空闲分区相邻且在空闲分区的下方*/
q->next->set_date(q->next->c_size + pp->c_size,q->next->c_begin,q->next->NO);
delete pp;
return;
}else if(q->next && q->c_begin + q->c_size == pp ->c_begin && pp ->c_begin + pp ->c_size == q ->next->c_begin){/*已分配分区与空闲分区相邻且在空闲分区的中间*/
q->set_date(q->c_size + q->next->c_size + pp->c_size,q->c_begin,q->NO);
struct frist_fit *qq = q->next;
q->next = q->next->next;
delete qq;
return;
}
}
pp ->set_date(pp->c_size,pp->c_begin); /*设置空闲分区状态为未分配*/
struct frist_fit *q =NULL;
for(q = create; q ->next; q = q ->next) /*把已分区插入到第一个比其起始地址大的未分配分区前*/
if(q->next->c_begin > pp->c_begin){
pp ->next = q->next;
q->next = pp;
return;
}
pp->next = NULL;
q->next = pp; /*把已分配分区插入到未分配分区前*/
return;
}
int main(int arc,char *agv[])
{
struct frist_fit *create = new frist_fit(); /*空闲分区链表*/
struct frist_fit *free = new frist_fit(); /*已分配分区链表*/
int C_size;
int change;
printf("please input memory size:\n");
scanf("%d",&C_size);
init(create,C_size); /*初始化空闲分区*/
printf("memory all size:\n");
Out(create); /*输出空闲分区信息*/
while((change = menu())){
switch(change){
case 1: c_malloc(create,free); break; /*分配空闲分区*/
case 2: c_free(create,free); break; /*回收空闲分区*/
case -1: printf("input wrong\n"); break;
}
/*输出信息*/
printf("\n进程所占分区\n");
Out(free);
printf("空闲分区\n");
Out(create);
}
return 0;
}