动态内存分配之循环首次适应算法

首先说明一下,这个程序可能还有隐藏的问题,但是我懒得改了。
对于此程序,有几点需要说明:
1.已分配区和空闲区是分别表示的
2.采用的是单向链表
3.采用了尾指针tail,单纯的用来指向尾空闲区域
4.写了3天,好吧,我确实很菜,但是引用请注明出处,谢谢了

    #include <stdio.h>
    #include <stdlib.h>
    #include <malloc.h>
    typedef struct progress
    {
        int id;//进程号 
        int size;// 大小
        int start;//起始地址 
        struct progress *next;  
    }NODE;
    NODE *head,*pnew,*frees,*tail;
    NODE *head1,*pnew1,*frees1,*tail1;
    int location=0;//用于指向尾部指针位置 
    int max=100;//定义分区的总大小 
    int rest=max;//尾空闲区的大小 
    void refresh();//紧凑技术 
    int first_fit(int sizes,int id);//循环首次适应算法
    void insert(int size,int loc,int id);//已分配链表的插入
    void create();//分配区的链表初始化 
    void create1();//创建空闲分区指针
    void add();//已分配链表的添加 
    void add1(int size,int loc);//空闲链表的插入 
    void add2(int size,int location,NODE *  t);//空闲链表的插入 
    void display();//输出 
    void pdelete();//已分配节点的回收 

    void refresh()//紧凑技术 
    {
        //紧凑其实就是将已分配的链表进行挪动,设置一个大小变量用来记录当前位置,然后剩下的 就是重新创建 
        //采用空的两个链表进行重新创建 
        NODE *p,*t,*pnews,*tails,*heads,*q; //
        int loca=0,n=1;//用于记录当前指针位置 
        rest=max;
        t=(NODE *)malloc(sizeof(NODE));//
        pnews=(NODE *)malloc(sizeof(NODE));//
        tails=(NODE *)malloc(sizeof(NODE));//
        heads=(NODE *)malloc(sizeof(NODE));  //创建头节点。 
        tails->next=NULL;
        heads->next=tails;
        for(p=head->next;p!=NULL;p=p->next) {
            if(n==1){
                tails->id=p->id;  //新节点数据域存放输入的进程块号 
                tails->size=p->size;
                tails->start=loca;
                loca+=p->size;
                tails->next=NULL; 
                n++;
            }
            else{
                t->id=p->id;  //新节点数据域存放输入的进程块号 
                t->size=p->size;
                t->start=loca;
                loca+=p->size;
                t->next=NULL;   //新节点指针域置NULL 
                tails->next=t;
                tails=t;
            }
            rest-=p->size;
        }
        head=heads;
        location=loca;
        tail=tails;
        //将空闲分区进行重置 
        tail1->next=NULL;  //头节点指针域置NULL
        head1->next=tail1;  // 开始时尾指针指向头节点
        tail1->size=max-loca;
        tail1->start=loca;
    }

    int first_fit(int sizes,int id){//循环首次适应算法,在此之前已经检查尾部能不能插,将指针移到空闲链表队首进行遍历 
                            // 找到合适的就分配,不能的话进行紧凑,紧凑完后继续分配
                            //需要输入的是所需分区的大小 
            NODE *p,*t;
            int a=22;
            for(p=head1;p->next!=NULL;p=p->next){
                if(p->next->size>sizes){//p指向合适分区的前驱结点 
                    //如果找到合适分区,进行分配 
                    //分配其实就是对已分配链表的插入和对空闲链表的修改或删除 
                    //对于已分配链表的操作                    
                    insert(sizes,p->next->start,id); //将分区插入到合适的位置      
                    //对于空闲链表。其实直接修改就行,指针 
                    p->next->start+=sizes;
                    p->next->size-=sizes; 
                    return 0;
                }
                if(p->next->size==sizes) {
                    printf("TESTELSE\n");
                    insert(sizes,a,id); //将分区插入到合适的位置 
                    //对空闲链表来说,如果等于就是对空闲链表的节点删除
                    printf("TEST===%d",p->next->next->start);
                    t=p->next->next;
                    p->next=t;
                    return 0;
                }   
            //  printf("p==NULL未执行%d\n",p->next);
                if(p->next==NULL){
                    printf("p==NULL执行\n");
                    break;
                }                   
            }
            if(p->next==NULL){
                //找不到可以分配的空闲分区,进行紧凑技术
                printf("找不到合适的空闲分区,进行紧凑:\n");
                refresh(); 
                //再比较紧凑后的分区,看是否能分配,然后输出结果 
                if(tail1->size<sizes)
                    printf("内存不足,请先释放内存!");                 
                else{
                    printf("紧凑完毕,请重新输入!\n");
                    add();
                }
            }

    }
    void insert(int size,int loc,int id)//已分配链表的插入 
    {
        //printf("TESTinsert\n");
        NODE *p,*q;
        q=(NODE *)malloc(sizeof(NODE));//
        //printf("TESTinsert%d\n",t->next->start);
        for(q=head;q->next->start<loc;)
            q=q->next;  //将q指向要插入节点的前驱节点
        printf("TESTinsert\n");
        pnew1=(NODE *)malloc(sizeof(NODE));
        pnew1->size=size;
        pnew1->start=loc;
        pnew1->id=id;
        p=q->next;
        q->next=pnew1;
        pnew1->next=p;
    }
    void create()//分配区的链表初始化 
    {
        int id,size;
        head=(NODE *)malloc(sizeof(NODE));  //创建头节点。 
        pnew=(NODE *)malloc(sizeof(NODE));
        tail=(NODE *)malloc(sizeof(NODE));
        head->next=NULL;  //头节点指针域置NULL
        tail=head;  // 开始时尾指针指向头节点
        printf("-------------------------\n");
        printf("输入进程id:");
        scanf("%d",&id);
        printf("输入进程大小:");
        scanf("%d",&size);
        if(size<rest){
        //  printf("TESTcr\n"); 
            rest-=size;
            //pnew=NULL;        
            pnew->id=id;  //新节点数据域存放输入的进程块号 
            pnew->size=size;
            pnew->start=location;
            location+=size;
            pnew->next=NULL;   //新节点指针域置NULL 
            tail=pnew;   //为指针指向当前的尾节点 
            head->next=tail;  //新节点插入到表尾 
            //tail=pnew;   //为指针指向当前的尾节点 
            //接下来是对空闲链表的操作
            tail1->size=max-size;
            tail1->start=location;
        }
        else
        printf("内存不足!\n");
    }
    void create1()//创建空闲分区指针 
    {
        tail1=(NODE *)malloc(sizeof(NODE));  //创建尾节点。 
        head1=(NODE *)malloc(sizeof(NODE));  //创建头节点。   
        pnew1=(NODE *)malloc(sizeof(NODE)); 
        head1->next=NULL;  //头节点指针域置NULL
        tail1=head1;  // 开始时尾指针指向头节点
        //pnew1=NULL;       
        pnew1->size=max;
        pnew1->start=0;
        pnew1->next=NULL;   //新节点指针域置NULL
        tail1=pnew1;   //为指针指向当前的尾节点  
        head1->next=tail1;  //新节点插入到表尾 
    //  tail1=pnew1;   //为指针指向当前的尾节点 
    }
    void add()//已分配链表的尾添加 
    {
        int id,size;
        pnew=(NODE *)malloc(sizeof(NODE));
        printf("输入进程id:");
        scanf("%d",&id);
        printf("输入进程大小:");
        scanf("%d",&size);
        if(rest>size){
            rest-=size;
        //    printf("TEST add\n");
            pnew->id=id;  //新节点数据域存放输入的进程块号 
            pnew->size=size;
            pnew->start=location;
            location+=size;
            pnew->next=NULL;   //新节点指针域置NULL 
            tail->next=pnew;  //新节点插入到表尾 
            tail=pnew;   //为指针指向当前的尾节点          
            //接下来是对空闲链表的操作
            tail1->size-=size;
            tail1->start=location;
        }
        else{
        //  printf("TEST addfit\n");
            first_fit(size,id);
        }
    }
    void add1(int size,int loc)//空闲链表的插入 
    {
        //第一次插入 
        //printf("TESTadd1\n"); 
        pnew1=(NODE *)malloc(sizeof(NODE));
        pnew1->size=size;
        pnew1->start=loc;
        head1->next=pnew1; 
        pnew1->next=tail1;
    }
    void add2(int size,int loc,NODE *t)//空闲链表的插入 
    {
        //非第一次插入 
        printf("TESTadd2\n"); 
        NODE *p;
        pnew1=(NODE *)malloc(sizeof(NODE));
        pnew1->size=size;
        pnew1->start=loc;
        p=t->next;
        t->next=pnew1;
        pnew1->next=p;
        tail1=p;
    }
    void display()//输出 
    {
         NODE *p;
         printf("当前已分配情况:\n");
        printf("--------------------------------------------\n");
        printf("起始地址     进程id     分区大小\n");
         for(p=head->next;p!=NULL;p=p->next){
         // printf("起始地址  进程id 分区大小\n");
          //  printf("--------------------------------------------\n");
            printf("%d             %d         %d\n",p->start,p->id,p->size);
         }
         printf("--------------------------------------------\n");
         printf("当前空闲分区情况:\n");
        printf("--------------------------------------------\n");
        printf("起始地址    分区大小\n");
         for(p=head1->next;p!=NULL;p=p->next){
         // printf("起始地址 分区大小\n");
         // printf("--------------------------------------------\n");
            printf("%d             %d\n",p->start,p->size);
         }
    } 
    void pdelete()
    {
        int id;
        printf("请输入您要回收的进程id:");
        scanf("%d",&id);
        NODE *p,*q,*t;
         for( p=head;p->next->id!=id;){
             p=p->next;  //将p指向要删除节点的前驱节点 
             if(p->next==NULL)  //表明链表中的节点不存在 
             {
                  printf("输入的id有误!");
                  pdelete(); 
             }  
         }
         if(p->next->next==NULL){//假设删除的是尾分配区,直接调整空闲分区各值即可 
            tail1->start=p->next->start;
             tail1->size+=p->next->size;
             p->next=NULL;
             tail1=p; 
             return;
         } 
    //     printf("TEST%d\n",head1->next->id); 
    //   printf("TEST%d\n",tail1->id); 
         if(head1->next->id==tail1->id)
         add1(p->next->size,p->next->start); 
         else{
             for(t=head1;t->next->start<p->next->start;)
             t=t->next;  //将t指向要插入空闲链表的前驱节点 
             add2(p->next->size,p->next->start,t);
         }
      //   printf("%d %d\n",p->next->size,p->next->start) ;
         q=p->next;  //q指向待删除的节点 
         p->next=q->next;  //删除节点
         free(q);   //释放节点的内存单元         
    }
    int main()
    {
        int n=1;
        int i;
        printf("--------------------------------------------\n");
        printf("说明:本内存分配系统采用的是循环首次适应算法\n");
        printf("--------------------------------------------\n");
        //printf("请输入要进行的操作:\n");
        while(1){
            printf("1.创建进程     |   2.撤销进程       |    0.退出\n");
            printf("请输入要进行的操作:");
        //  printf("1.创建进程     |   2.撤销进程       |0.退出\n");
            scanf("%d",&i);
            pnew=(NODE *)malloc(sizeof(NODE));
            pnew1=(NODE *)malloc(sizeof(NODE));
            switch(i){
                case 1:
                    if(n==1){                   
                        create1();
                        create();
                        n++;
                        display();
                    }
                    else{
                        add();
                        display();
                    }
                    break;
                case 2:                 
                    pdelete();
                    display();
                    break;
                case 0:exit(0);
            } 
        }
        return 0; 
    }
  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值