c模拟内存管理

// 内存管理
#include<stdio.h>
#include<stdlib.h>
const int SIZE=100;
const int MAX=65; //最大进程数
const int DEBUG=0;//调试开关


struct mem //内存块结构
{

int pr_num;

char * start_addr;

int size;

struct mem * next;

};
int siquence[MAX];
void showmem(char *);//显示内存分配情况
void Menu(void );//显示操作信息
int getnum(void );//获取进程序号
void insert(struct mem *,struct mem *);//将释放内存控制块插入到free列队中
int check(int n);//判断是否存在序号为n的进程,存在返回1
void showmcb(struct mem *,int i);//将free,used的信息输出
void ch_siquence(int);//进程序列号变反
void writemem(char *addr,int snum,int size );//对内存写入
void deletmem(char *addr,int size);//撤消内存内容
void freeunion(struct mem * );//合并空闲表


int main(void)
{

struct mem *free,*sta_free=NULL,*used,*sta_used,*change;

char * mem_addr,*staticmem;

char commu;

int pro_size,flag=0,snum,i;//flag标志是否获得内存

struct mem *temp=sta_free,*p,*temp_used;

staticmem=mem_addr=(char *)malloc(SIZE*sizeof(char));//分配内存

for(i=0;i<MAX;i++) //进程序列初始化

   siquence[i]=0;

for( i=0;i<SIZE;i++,mem_addr++)   //内存初始化

{

*mem_addr='_';

sta_free=free=(struct mem*)malloc(sizeof(struct mem));

sta_used=used=(struct mem*)malloc(sizeof(struct mem));

free->pr_num=-1;

free->start_addr=staticmem;

free->size=SIZE;

free->next=NULL;

used->pr_num=0;

used->start_addr=NULL;

used->size=0;

used->next=NULL;

}

int cycle=1;

while(cycle)

{   

   Menu(); //显示主菜单

   scanf("%c%*c",&commu);

   /*判断输入的字符是否大小写合法*/

   switch(commu)

   {//switch begin

   case 'g':

   {//为进程分配内存

   printf("请输入需要的内存大小:");

   scanf("%d",&pro_size);

   for(flag=0,temp=sta_free;temp!=NULL;temp=temp->next)

   {

    if(temp->size>=pro_size) 

    {//分配新的内存管理块

      p=(struct mem *)malloc(sizeof(struct mem));

      p->pr_num=getnum();

      p->start_addr=temp->start_addr;

      p->size=pro_size;

      p->next=NULL; 

    writemem(p->start_addr,p->pr_num,p->size);//写内容

    temp->start_addr=temp->start_addr+pro_size;

    temp->size=temp->size-pro_size;

    flag=1;

    }

   }//end while

   if(flag==1)
   {
    if(DEBUG) printf("已做过flag==1部分\n");
     //将新管理块插入到used列队中
    for(temp_used=sta_used;temp_used->next!=NULL;)
     temp_used=temp_used->next;
          temp_used->next=p;   
    printf("成功分配内存块\n请按任意键继续......\n");
   }
   else printf("分配内存出错,无法分配所需内存!\n请按任意键继续......\n");
   }
   getchar();
   break;
   case 'd':
   {//释放内存snum
   printf("输入要释放的进程号:");
   scanf("%d",&snum);
   if(check(snum)==1)//判断输入的号码是否正确
   {
     //序号正确
    for(temp_used=sta_used;temp_used->next!=NULL&&temp_used->next->pr_num!=snum;)
     temp_used=temp_used->next;//往下寻找snum序号
    if(temp_used->next!=NULL)
    {//找到所需释放的进程
     deletmem(temp_used->next->start_addr,temp_used->next->size);//删除内容
     ch_siquence(temp_used->next->pr_num);//进程号变反
     temp_used->next->pr_num=-1;//撤消进程号
     change=temp_used->next;
     temp_used->next=temp_used->next->next;//将内存块从used队列中删除
     insert(sta_free,change);//将所需释放的内存块插入到free队列中
     freeunion(sta_free);
     printf("释放进程%d成功\n请按任意键继续......\n",snum);
    }
   }
   else printf("出错,该序号无效\n请按任意键继续......\n");
   }
   break;
   case 's':
   { //显示目前内存分配情况
    showmem(staticmem);
    printf("内存起始地址:%d\n",staticmem);
    showmcb(sta_free,0);
    showmcb(sta_used,1);
    printf("请按任意键继续......\n");
   }
   break;
   case 'b':
    {
     printf("请按任意键继续......\n");
     cycle=0;
     break;
    }
   default:
    {
     printf("对不起,你的输入不合法,请确保你的输入为g,d,s,b中的任一个\n");
     printf("请按任意键继续......\n");
    }
   }
   getchar();
//getchar();
}
return 0;
}//main函数结束






void Menu(void)
{
system("color 9f");
printf("\t      输入命令\n");
printf("\t   ===============\n");
printf("\t    g--分配内存\n");
printf("\t    d--释放内存\n");
printf("\t    s--显示信息\n");
printf("\t    b--退出系统\n");
printf("\t   ===============\n");
printf("\t    请选择:");
}
void showmem(char *mem_addr)
{
int i;
printf("\n内存内容:\n");
for(i=1;i<=SIZE;i++,mem_addr++)
{
   printf("%c ",*mem_addr);
   if(i%20==0)
    printf("\n");
}
printf("\n");
}
int getnum(void )
{
//获取进程序号
int i;
for(i=0;siquence[i]>0;)
   i++;
if(siquence[i]==0)
{ siquence[i]=i+1;
    return siquence[i] ;
}
else
{
    siquence[i]*=-1;
return siquence[i];
}

}

void insert(struct mem *base,struct mem *p)
{//将释放内存控制块插入到free列队中
for(;base->next!=NULL&&p->start_addr<base->next->start_addr;)
   base=base->next;
if(base->next==NULL)
{//已到末尾,在末尾插入p
   base->next=p;
   p->next=NULL;
}
else
{ //在链表中间插入p
   p->next=base->next;
   base->next=p;
}
}
int check(int n)
{ //判断是否存在序号为n的进程,存在返回1
for(int i=0;siquence[i]!=0;i++)
   if(siquence[i]==n)
   {
    return 1;
    break;
   }
   return 0;
  
}
void showmcb(struct mem * base,int i)
{
//将空闲,分派内存的信息输出
if(i==0)
{
printf("-----------------------------------------\n");
printf("空闲表:\n");
for(;base!=NULL;base=base->next)
   printf("起始地址%d:大小%d\n",base->start_addr,base->size);
printf("----------------------------------------\n");
}
if(i==1)
{
printf("已分配表:\n");
for(base=base->next;base!=NULL;base=base->next)
   printf("进程号%d,起始地址%d:大小%d\n",base->pr_num,base->start_addr,base->size);
printf("-----------------------------------------\n");
}
}
void ch_siquence(int n)
{
//进程序列号变反
for(int i=0;siquence[i]!=0;i++)
   if(siquence[i]==n)
    siquence[i]*=-1;
}
void writemem(char *addr,int snum,int size )
{
//对内存写入
for(int i=1;i<=size;i++,addr++)
   *addr=snum+'0';
}

void deletmem(char *addr,int size)
{
//撤消内存内容
for(int i=1;i<=size;i++,addr++)
   *addr='_';
}
void freeunion(struct mem * base)
{
//对空闲表中相邻的空闲块合并 
for(;base!=NULL;)
{
   if(base->next!=NULL&&base->start_addr==base->next->start_addr+base->next->size)
   {
    base->start_addr=base->next->start_addr;
    base->size=base->size+base->next->size;
    base->next=base->next->next;
   }
   else base=base->next;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值