内存管理源程序

#include<stdio.h>

#include<stdlib.h>

#include<time.h>

#include<string.h>

#include<math.h>


#define Free 0        //空闲状态

#define Busy 1        //已用状态

#define OK 1          //成功

#define ERROR 0       //失败


#define ENC 40960      //空闲内存空间最大限

#define PNC 40960      //申请内存空间最大限制

#define TC 10         //测试次数


#define pi 3.1415926535897932384626   //pi值,正太分布函数


#define MAX_Length (256*1024)  //最大内存空间256MB

#define MIN_Length (56*1024)   //系统保留区


typedef unsigned long DIZHI;


void ChuShiHuaNC(DIZHI,DIZHI);  //初始化内存

int ShenQingNC(unsigned long,int);        //申请内存

int HuiShouNC(DIZHI);           //回收内存

int First_fit(unsigned long);    //首次适应算法

int Next_fit(unsigned long);     //循环首次适应算法

int Best_fit(unsigned long);     //最佳适应算法

int Worst_fit(unsigned long);    //最坏适应算法


void Sort_Array(int);           //排序


void Initblock();                //带头结点的内存空间链表

void InitNC(int);                   //初始化空闲分区表

void Print1();                    //输出空闲分区表

void PrintID(int);                  //输出记录

void show();                        //输出内存函数

void RandTest();                     //产生测试随机数


double randn(double miu,double sigma, int min ,int max);


int m = 1;                         //选择条用哪个算法来处理

int TNC[5000] = {0};

int Tf[5000] = {0};

int sum11 = 0;

int id_flag_nf[10000] = {0};

int sx = 0,tx = 0;

int countnf[5000] = {0};

int countnfc = -1;

int count = 0;                               //记录分区号

int TCount = 0;

int id_flag_ff[5000] = {0};

int countff[5000] = {0};

int countffc = -1;

int sumsum = 0;

double sumt[5000] = {0};

int id_flag_bf[10000] = {0};

int countbf[5000] = {0};

int countbfc = -1;

int id_flag_wf[10000] = {0};

int countwf[5000] = {0};

int countwfc = -1;

int idf = 1;

int x = 10;


typedef struct FreeArea         //空闲分区表结构

{

int ID,state;                   //状态

unsigned long size;           // 分区大小

DIZHI address;             //地址


}ElemType;


typedef struct DulNode            //双向链表

{

ElemType data;                //分区数据

struct DulNode * prior;        //前驱指针

struct DulNode * next;         //后继指针

}DulNode,*DulLinkList;


DulLinkList first_node;             //头结点

DulLinkList last_node;              //尾节点

DulLinkList r;


void Initblock() {                   //双链表初始化

first_node = (DulLinkList)malloc(sizeof(DulNode));

last_node = (DulLinkList)malloc(sizeof(DulNode));

first_node->prior = NULL;

first_node->next = last_node;

last_node->prior = first_node;

last_node->next = NULL;

first_node->data.ID = 0;

first_node->data.size = MIN_Length - 1;   //0到56MB-1为系统保留区

first_node->data.state = Busy;

first_node->data.address = 0;

last_node->data.ID = 1;

last_node->data.size = MAX_Length - MIN_Length;

last_node->data.state = Free;

last_node->data.address = MIN_Length;

}


void clearNC()

{

DulLinkList d = first_node->next;

d = d->prior;

while(1)

{

if(d->next!=NULL)

{

first_node = first_node->next;

d = d->next;

free(first_node->prior);

}

else

{

//free(first_node);

break;

}

}

sum11 = 0;

count = 0;

sx = 0,tx = 0;

countnfc = -1;

TCount = 0;

countffc = -1;

sumsum = 0;

countbfc = -1;

countwfc = -1;

idf = 1;

int i =0;

for(i=0;i<5000;i++)

{

id_flag_nf[i] = 0;

id_flag_ff[i] = 0;

id_flag_bf[i] =0;

id_flag_wf[i] =0;

countbf[i] =0;

countff[i] =0;

countnf[i] =0;

countwf[i] =0;

sumt[i] =0;

}


}


void ChuShiHuaNC(DIZHI zKS_KYNC,DIZHI zJS_KYNC) {                   //空闲块链表建立

DulLinkList p = (DulLinkList)malloc(sizeof(DulNode));

p->data.address = zKS_KYNC;

p->data.ID = count + 1;                //分区号从1开始

p->data.size = zJS_KYNC - zKS_KYNC;

p->data.state = Busy;

p->prior = last_node->prior;                //双链表插入节点

last_node->prior->next = p;

p->next = last_node;

last_node->prior = p;

count = count + 1;


last_node->data.ID = count+1;

last_node->data.address = zJS_KYNC;

last_node->data.size = MAX_Length - zJS_KYNC;

last_node->data.state = Free;

TCount = count;

}


void show()

{

int i = 0;

DulLinkList sr = first_node->next;

sr = sr->prior;

printf("当前内存状况\n");

printf("ID\t内存大小\t内存地址\t状态\n");

for(i = 0;;i++)

{

if(sr!=NULL)

{

printf("%d\t%d\t\t%d\t\t%d\n",sr->data.ID,sr->data.size,sr->data.address,sr->data.state);

if(sr->next!=NULL)

sr = sr->next;

else

break;

}

}

}


void RandTest()

{

FILE* fileout;

fileout = fopen("申请内存大小.txt","wt");

int i = 0,a;

double miu = PNC / TC;

double sigma = (PNC - miu) / TC;

int min = 1;

int max = PNC;

srand(time(0));               //随机数种子

for(i = 0;i<x;i++)

{

a = (int)randn(miu,sigma,min,max);              //正态分布产生随机种子

TNC[i] = a;

fprintf(fileout,"%d\n",TNC[i]);

Tf[i] = rand()% (MAX_Length - MIN_Length) + MIN_Length;

}

}


void InitNC(int m)                             //空闲分区链的建立

{

int i = 0,a = 0,sum = 0,c = 0,b,mh;

double decide;

double miu = PNC / TC;

double sigma = (PNC - miu) / TC;

int min = 1;

int max = PNC;

FILE *fileout1;

if(m == 1)

{

fileout1 = fopen("内存利用率ff.txt","wt");

}

if(m == 2)

{

fileout1 = fopen("内存利用率nf.txt","wt");

}

if(m == 3)

{

fileout1 = fopen("内存利用率bf.txt","wt");

}

if(m == 4)

{

fileout1 = fopen("内存利用率wf.txt","wt");

}

Initblock();

srand(time(0));               //随机数种子

for(i = 0;i<x;i++)

{

decide = rand()*1.0 / RAND_MAX;

if(decide > 0.5||i<3)

{

a = TNC[i];

printf("申请的内存大小为:%d\n",a);

//show();

b = ShenQingNC(a,m);

if(b == 1 && sum+a < MAX_Length - MIN_Length)

sum += a;

sumt[i] = sum*1.0 / (MAX_Length - MIN_Length);

fprintf(fileout1,"%f\n",sumt[i]);

}

else

{

c = Tf[i];

//c = rand()% (MAX_Length - MIN_Length) + MIN_Length;           //保证回收地址为合法的地址空间

printf("回收地址为%d\n",c);

//show();

mh = HuiShouNC(c);

printf("\n");

if(sum - mh >0)

sum -= mh;

sumt[i] = sum*1.0 / (MAX_Length - MIN_Length);

fprintf(fileout1,"%f\n",sumt[i]);

}

}

}


int First_fit(unsigned long zDX) {                      //首次适应算法

DulLinkList g = first_node->next;                   //记录头结点

g = g->prior;

countffc ++;

while(zDX > 0)

{

countff[countffc] ++;

if(g->next != NULL)

{

g = g->next;

}

else

{

return ERROR;

break;

}

if(g->data.state == Free && g->data.size == zDX)    //刚好相等,改变状态位

{

g->data.state = Busy;

id_flag_ff[g->data.ID] = id_flag_ff[g->data.ID] + 1;

return OK;

break;

}

if(g->data.state == Free && g->data.size > zDX)    //有空闲,划分出去

{

id_flag_ff[g->data.ID] = id_flag_ff[g->data.ID] + 1;

if(g->data.ID == last_node->data.ID && sum11 < MAX_Length - MIN_Length)

{

sum11 +=  zDX;

ChuShiHuaNC(MIN_Length+sum11 -  zDX,MIN_Length+sum11);

return OK;

break;

}

else

{

g->data.address = g->data.address + zDX;

g->data.size = g->data.size - zDX;

return OK;

break;

}

}

}

return ERROR;

}


int Next_fit(unsigned long zDX)                    //循环首次适应算法

{

if(sx == 0)

{

r = first_node->next;                //初始化r

r = r->prior;

sx = 1;

}

countnfc++;

int st = 0;

while(zDX > 0)

{

countnf[countnfc]++;

if(r == NULL && tx == 0)

{

r = first_node->next;                //回到开头

r = r->prior;

tx = 1;

}

else if(r == NULL&& tx == 1)

{

return ERROR;

break;

}

else if(r->next != NULL)

r = r->next;

if(r->data.state == Free && r->data.size == zDX)    //刚好相等,改变状态位

{

r->data.state = Busy;

id_flag_nf[r->data.ID] = id_flag_nf[r->data.ID] + 1;

return OK;

break;

}

if(r->data.state == Free && r->data.size > zDX)    //有空闲,划分出去

{

id_flag_nf[r->data.ID] = id_flag_nf[r->data.ID] + 1;

sum11 +=  zDX;

if(sum11 < MAX_Length - MIN_Length)

{

ChuShiHuaNC(MIN_Length+sum11 -  zDX,MIN_Length+sum11);

return OK;

break;

}

else

{

r->data.address = r->data.address + zDX;

r->data.size = r->data.size - zDX;

return OK;

break;

}

}

if( r->data.size < zDX && r->data.ID == last_node->data.ID && st == 0)

{

r = first_node->next;

r = r->prior;

st = 1;

}

else

{

return ERROR;

break;

}

}

}


void Sort_Array(int ud)                                //排序,ud为1时为升序,ud为2时为降序,ud为3按id升序

{

int a1[10000];

int a2[10000];

int a3[10000];

int a4[10000];

int ch;

DulLinkList g = first_node->next;                   //记录头结点

g = g->prior;

int st = 0;

int i = 0,j = 0;

for(i = 0;g->next!=NULL;i++)

{

g = g->next;

a1[i+1] = g->data.ID;

a2[i+1] = g->data.size;

a3[i+1] = g->data.address;

a4[i+1] = g->data.state;

st++;

}

if(ud == 1)                                          //升序排列

{

for(i=1;i<=st-1;i++)

{

for(j = i+1;j <=st;j++)

{

if(a2[i] >= a2[j])

{

ch = a1[i];

a1[i] = a1[j];

a1[j] = ch;

ch = a2[i];

a2[i] = a2[j];

a2[j] = ch;

ch = a3[i];

a3[i] = a3[j];

a3[j] = ch;

ch = a4[i];

a4[i] = a4[j];

a4[j] = ch;

}

}

}

}

if(ud == 2)                                            //降序排列

{

for(i=1;i<=st-1;i++)

{

for(j = i+1;j <=st;j++)

{

if(a2[i] <= a2[j])

{

ch = a1[i];

a1[i] = a1[j];

a1[j] = ch;

ch = a2[i];

a2[i] = a2[j];

a2[j] = ch;

ch = a3[i];

a3[i] = a3[j];

a3[j] = ch;

ch = a4[i];

a4[i] = a4[j];

a4[j] = ch;

}

}

}

}

if(ud == 3)

{

for(i=1;i<=st-1;i++)

{

for(j = i+1;j <=st;j++)

{

if(a1[i] >= a1[j])

{

ch = a1[i];

a1[i] = a1[j];

a1[j] = ch;

ch = a2[i];

a2[i] = a2[j];

a2[j] = ch;

ch = a3[i];

a3[i] = a3[j];

a3[j] = ch;

ch = a4[i];

a4[i] = a4[j];

a4[j] = ch;

}

}

}

}

while(1)

{

if(first_node->next!=NULL)

{

first_node = first_node->next;

free(first_node->prior);

}

else

{

free(first_node);

break;

}

}

Initblock();

for(i = 1;i<= st;i++)

{

DulLinkList p = (DulLinkList)malloc(sizeof(DulNode));

p->data.address = a3[i];

p->data.ID = a1[i];

p->data.size = a2[i];

p->data.state = a4[i];

if(i == st)

{

last_node->data.ID = a1[i];

last_node->data.address = a3[i];

last_node->data.size = a2[i];

last_node->data.state = a4[i];

}

else

{

p->prior = last_node->prior;                 //双链表插入节点

last_node->prior->next = p;

p->next = last_node;

last_node->prior = p;

}

}

}


int Best_fit(unsigned long zDX)                   //最佳适应算法

{

Sort_Array(1);                       //升序排列

//printf("排序后");

//show();

//system("pause");

countbfc++;

DulLinkList u = first_node->next;                   //记录头结点

u = u->prior;

while(zDX > 0)

{

countbf[countbfc]++;

if(u->next != NULL)

{

u = u->next;

}

else

{

return ERROR;

break;

}

if(u ->data.size == zDX && u->data.state == Free)

{

u->data.state = Busy;

id_flag_bf[u->data.ID] =  id_flag_bf[u->data.ID] + 1;

return OK;

break;

}

if(u->data.size > zDX && u->data.state == Free)

{

id_flag_bf[u->data.ID] += 1;

if(u->data.ID == idf && sum11 < MAX_Length - MIN_Length)

{

sum11 +=  zDX;

Sort_Array(3);

ChuShiHuaNC(MIN_Length+sum11 -  zDX,MIN_Length+sum11);

idf = last_node->data.ID;

return OK;

break;

}

else

{

u->data.address = u->data.address + zDX;

u->data.size = u->data.size - zDX;

return OK;

break;

}

return OK;

break;

}

}

   return ERROR;

}


int Worst_fit(unsigned long zDX) {                        //最坏适应算法

Sort_Array(2);                                       //降序排列

//printf("排序后");

//show();

//system("pause");

DulLinkList h = first_node->next;                   //记录头结点

h = h->prior;

countwfc++;

while(zDX > 0)

{

countwf[countwfc]++;

if(h->next != NULL)                     //如果没有循环到最后就继续

{

h = h->next;

}

else

{

return ERROR;

break;

}

if(h->data.size < zDX && h->data.state == Free)                       //如果最大都不满足,则失败

{

return ERROR;

break;

}

if(h ->data.size == zDX && h->data.state == Free)

{

h->data.state = Busy;

id_flag_wf[h->data.ID] =  id_flag_wf[h->data.ID] + 1;

return OK;

break;

}

if(h->data.size > zDX && h->data.state == Free)

{

id_flag_wf[h->data.ID] = id_flag_wf[h->data.ID] + 1;

if(h->data.ID == idf && sum11 < MAX_Length - MIN_Length)

{

sum11 +=  zDX;

Sort_Array(3);

ChuShiHuaNC(MIN_Length+sum11 -  zDX,MIN_Length+sum11);

idf = last_node->data.ID;

return OK;

break;

}

else

{

h->data.address = h->data.address + zDX;

h->data.size = h->data.size - zDX;

return OK;

break;

}

return OK;

break;

}

}

return ERROR;

}


int ShenQingNC(unsigned long zDX,int m)                           //申请内存

{

if(m == 1)                                  //首次适应

{

if(First_fit(zDX))

{

   printf("申请内存成功\n\n");

return OK;

}

else

{

printf("申请内存失败\n\n");

return ERROR;

}

}

if(m == 2)                          //循环首次适应

{

if(Next_fit(zDX))

{

printf("申请内存成功\n\n");

return OK;

}

else

{

printf("申请内存失败\n\n");

return ERROR;

}

}

if(m == 3)                             //最佳适应

{

if(Best_fit(zDX))

{

printf("申请内存成功\n\n");

return OK;

}

else

{

printf("申请内存失败\n\n");

return ERROR;

}

}

if(m == 4)                                     //最坏适应

{

if(Worst_fit(zDX))

{

printf("申请内存成功\n\n");

return OK;

}

else

{

printf("申请内存失败\n\n");

return ERROR;

}

}

return ERROR;

}


int HuiShouNC(DIZHI zKSDZ)                  //回收内存

{

int ght = 0;

if(m == 3 || m == 4)

Sort_Array(3);

DulLinkList t = first_node->next;                   //记录头结点

t = t->prior;

while(zKSDZ > MIN_Length)

{

if(t->next!=NULL)

t = t->next;

if(zKSDZ < t->data.address)

{

t = t->prior;

break;

}

if(t->next == NULL)

{

break;

}

}

if(t->data.ID == 0)

t = t->next;

if(t->data.state == Busy)

ght = t->data.size;

else if(t->next!=NULL)

ght = t->next->data.address - t->prior->data.address-t->prior->data.size - t->data.size;

else if(t->prior->data.ID != 0)

ght = MAX_Length - t->prior->data.address-t->prior->data.size - t->data.size;

else

ght = MAX_Length - MIN_Length - t->data.size;

if(t->prior->data.ID == 0&&t->next!=NULL)                         //头节点

{

if(t->next->data.state == Free&&t->next->next!=NULL)

{

t->data.size = t->next->next->data.address-t->prior->data.address-t->prior->data.size;

t->data.state = 0;

t->next = t->next->next;

t->next->prior = t->prior->next;

}

else

{

t->data.state = 0;

t->data.size = t->next->data.address - t->prior->data.address-t->prior->data.size;

}

}

else if(t->next == NULL&&t->prior->data.ID!=0)                        //尾节点

{

if(t->prior->data.ID == Free)

{

t = t->prior;

t->data.size = MAX_Length - t->prior->data.address-t->prior->data.size;

t->data.state = Free;

}

else

{

t->data.state = Free;

t->data.size = MAX_Length - t->data.address;

}

}

else if(t->prior->data.ID == 0 && t->next == NULL)                        //只有一个分区

{

t->data.state = 0;

}

else if(t->prior->data.state == Free && t->next->data.state == Busy)            //与前一分区相连

{

t->data.state = Free;

t->prior->data.address = t->prior->prior->data.address+t->prior->prior->data.size;

t->prior->data.size = t->next->data.address-t->prior->prior->data.address- t->prior->prior->data.size;

t->prior->next = t->next;

t->next->prior = t->prior;

}

else if(t->next->data.state == Free && t->prior->data.state == Busy)           //与后一分区相连

{

t->data.state = Free;

t->data.address = t->prior->data.address+t->prior->data.size;

if(t->next->next!=NULL)

{

t->data.size = t->next->next->data.address - t->prior->data.address - t->prior->data.size;

t->next->next->prior = t;

t->next = t->next->next;

}

else

{

t->next->data.size = MAX_Length - t->prior->data.address - t->prior->data.size;

t->prior->next = t->next;

t->next->prior = t->prior;

}

}

else if(t->next->data.state == Free && t->prior->data.state == Free)             //与前后两分区相连

{

t->data.state = Free;

t->data.address = t->prior->data.address+t->prior->data.size;

if(t->next->next!=NULL)

{

t->prior->data.size = t->next->next->data.address-t->prior->prior->data.address- t->prior->prior->data.size;

t->prior->next = t->next->next;

t->next->prior = t->prior;

}

else

{

t->next->data.size =MAX_Length-t->prior->prior->data.address- t->prior->prior->data.size;

t->prior->prior->next = t->next;

t->next->prior = t->prior->prior;

}

}

else              //都不相连

{

t->data.state = Free;

t->data.address = t->prior->data.address + t->prior->data.size;

t->data.size = t->next->data.address - t->data.address;

}

return ght;

}


void PrintID(int m)

{

int i = 1;

FILE *fileout,*fileout1;

if(m==1)                                                   //首次适应算法

{

fileout = fopen("分配记录IDff.txt","wt");

fileout1 = fopen("每次申请查询次数ff.txt","wt");

while(1)

{

if(id_flag_ff[i] > 0)

{

fprintf(fileout,"%d\t%d\n",i,id_flag_ff[i]);

}

else

break;

i++;

}

int sum1 = 0;

for(i = 0;i <= countffc;i++)

{

sum1 += countff[i];

fprintf(fileout1,"%d\n",countff[i]);

}

}

if(m == 2)                                             //循环首次适应算法

{

fileout = fopen("分配记录IDnf.txt","wt");

fileout1 = fopen("每次申请查询次数nf.txt","wt");

while(1)

{

if(id_flag_nf[i] > 0)

{

fprintf(fileout,"%d\t%d\n",i,id_flag_nf[i]);

}

else

break;

i++;

}

int sum1 = 0;

for(i = 0;i <= countnfc;i++)

{

sum1 += countnf[i];

fprintf(fileout1,"%d\n",countnf[i]);

}

}

if(m == 3)                                         //最佳适应

{

fileout = fopen("分配记录IDbf.txt","wt");

fileout1 = fopen("每次申请查询次数bf.txt","wt");

while(1)

{

if(id_flag_bf[i] > 0)

{

fprintf(fileout,"%d\t%d\n",i,id_flag_bf[i]);

}

i++;

if(i > 4000)

break;

}

int sum1 = 0;

for(i = 0;i <= countbfc;i++)

{

sum1 += countbf[i];

fprintf(fileout1,"%d\n",countbf[i]);

}

}

if(m == 4)                                            //最坏适应

{

fileout = fopen("分配记录IDwf.txt","wt");

fileout1 = fopen("每次申请查询次数wf.txt","wt");

while(1)

{

if(id_flag_wf[i] > 0)

{

fprintf(fileout,"%d\t%d\n",i,id_flag_wf[i]);

}

i++;

if(i > 4000)

break;

}

int sum1 = 0;

for(i = 0;i <= countwfc;i++)

{

sum1 += countwf[i];

fprintf(fileout1,"%d\n",countwf[i]);

}

fprintf(fileout1,"%f",sum1*1.0/(countwfc+1));

}

fclose(fileout);

}



double Rand(int min,int max)                 //产生[min,max]区间的随机数

{

return min+(max-min)*rand()/(RAND_MAX+1.0);

}


double normal(double x, double miu,double sigma)            //正太分布函数

{

   return 1.0/sqrt(2*pi)/sigma*exp(-1*(x-miu)*(x-miu)/(2*sigma*sigma));

}


double randn(double miu,double sigma, int min ,int max)

{

   double x,y,dNC;

   do{

       x=Rand(min,max);                                //产生随机数

       y=normal(x,miu,sigma);                          //转化为正太分布

       dNC=Rand(0.0,normal(miu,miu,sigma));           //产生正太分布的随机数

   }while(dNC>y);                                     //如果不是正太分布随机数就继续

   return x;                                          //返回产生的随机数

}


void Print1()

{

FILE *fileout;

fileout = fopen("最后内存分区表.txt","wt");

int i = 0;

fprintf (fileout,"分区号\t大小/KB\t起址/KB\t状态\n");

DulLinkList q = first_node->next;                //记录头结点

q = q->prior;

for(i = 0;;i++)

{

if(q->next != NULL)

q = q->next;

else

break;

fprintf(fileout,"%d\t%d\t%d\t%d\n",q->data.ID,q->data.size,q->data.address,q->data.state);

}

fclose(fileout);

}


int main()

{

printf("请输入申请内存的次数\n");

scanf("%d",&x);

printf("\t\t请选择你要测试的分配算法:\n");

printf("**************************************************\n");

printf("\t1为首次适应算法\t2为循环首次适应算法\n");

printf("\t3为最佳适应算法\t4为最坏适应算法\n");

printf("**************************************************\n");

char yn;

RandTest();

while(1)

{

printf("请选择算法:");

scanf("%d",&m);

printf("\n");

InitNC(m);

Print1();

PrintID(m);

clearNC();

printf("执行成功,结果已存入工程根目录文件中\n");

system("pause");

printf("是否继续(Y/N)\n");

getchar();

while(1)

{

scanf("%c",&yn);

if(yn =='Y'|| yn =='y' || yn == 'N' || yn == 'n')

break;

else

printf("请选择是否继续\n");

}

if(yn == 'N'|| yn == 'n')

break;

}

system("pause");

return 0;

}


你可能感兴趣的:(内存管理,源程序)