动态内存分区分配方式模拟

假设初始态下,可用内存空间为640K,并有下列请求序列,请分别用首次适应算法和最佳适应算法为作业分配和回收内存块,并显示出每次分配和回收后的空闲分区链的情况来以及内存占用情况图。

这是我做的一道大作业题目。在此与大家分享一下.

----------------------------

执行截图

动态内存分区分配方式模拟_第1张图片

----------------------------


/*
* description:动态内存分区分配方式模拟
* author:rayment
* creat date:2010-11-17
*/
#include <iostream>

using namespace std;

/*
*定义空闲分区链结构
*/
struct SubareaNode
{
    //分区起始地址
    int address;
    //分区大小
    int size;
    //分区状态(0,1)
    int state;
    //作业号
    int taskNo;
    //分区前向指针
    SubareaNode *prior;
    //分区后向指针
    SubareaNode *next;
};

/*
*定义动态分区分配类
*/
class DynamicSubareaAlloction
{
    private:
        //内存分区链指针
        SubareaNode *head;
        //内存空间大小
        int MEMORYSPACE;


    public:
        /*
        *在构造函数中初始化内存大小
        */
        DynamicSubareaAlloction()
        {
            cout << "请输入内存可用空间大小(大小范围50k至1000k):" << endl;
            do
            {
                cin >> MEMORYSPACE;
                if((MEMORYSPACE<50) || (MEMORYSPACE>1000))
                {
                    cout << "不符合内存可用空间大小范围!" << endl;
                }
            }while((MEMORYSPACE<50) || (MEMORYSPACE>1000));

            cout <<"------内存空间可用为" << MEMORYSPACE << "k------" << endl;
        }

        /*
        *对内存进行分区分配
        *int:内存分配算法选项
        */
        void execAlloction(int option)
        {
            //初始内存分区链
            head = new SubareaNode;
            head->size = MEMORYSPACE;
            head->address = 0;
            head->state = 0;
            head->taskNo = 0;
            head->prior = NULL;
            head->next = NULL;
            //定义作业号范围变量
            int task[10]={0,0,0,0,0,0,0,0,0,0};
            //操作选项变量
            int selectItem = 0;
            //作业号变量
            int no;
            //内存大小变量
            int space;
            //是否显示内存情况
            bool isShow;

            if(1 == option)
            {
                cout << "你选择了首次适应算法!" << endl;
            }
            else if(2 == option)
            {
                cout << "你选择了最佳适应算法!" << endl;
            }

            //选择申请或释放内存操作
            while(1)
            {
                cout << "==========================";
                cout << "/n请选择一项操作:";
                cout << "/n 1--申请内存";
                cout << "/n 2--释放内存";
                cout << "/n 0--终止操作";
                cout << "/n==========================/n";
                do
                {
                    cin >> selectItem;
                    if(1!= selectItem && 2!= selectItem && 0!= selectItem)
                    {
                        cout << "输入选项错误,请重新输入!" << endl;
                    }
                }while(1!= selectItem && 2!= selectItem && 0!= selectItem);
                //退出程序
                if(0 == selectItem)
                {
                    //释放内存分区链
                    delete head;
                    head = NULL;
                    break;
                }
                //检查作业号是否有效
                while(1)
                {
                    cout << "请输入作业号:(作业号范围1~10),输入'0'终止操作!" <<endl;
                    cin >> no;
                    //终止操作
                    if(0 == no) break;

                    if(no < 1 || no > 10)
                    {
                        cout << "超出作业号范围!" <<endl;
                    }
                    else if(1 <= no <= 10)
                    {
                        if(1 == task[no-1] && 1 == selectItem)
                        {
                            cout << "此作业号已申请内存,重新输入!" << endl;
                        }
                        else if(0 == task[no-1] && 2 == selectItem)
                        {
                            cout << "此作业号已释放内存,重新输入!" << endl;
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                //终止操作
                if(0 == no) break;
                isShow = true;
                //申请内存操作
                if(1 == selectItem)
                {
                    //检查申请内存大小是否有效
                    cout << "请输入申请内存大小:(单位:k)" << endl;
                    cin >> space;
                    while(space > MEMORYSPACE)
                    {
                        cout << "申请内存大小超过总共内存空间(" << MEMORYSPACE << "k),重新输入!" << endl;
                        cin >> space;
                    }
                    if(1 == option)
                    {
                        //首次适应算法内存分配
                        //如果申请失败,不显示内存情况
                        if(!firstFit_alloc(head,&space,&no,task)) isShow = false;
                    }
                    else
                    {
                        //最佳适应算法内存分配
                        //如果申请失败,不显示内存情况
                        if(!bestFit_alloc(head,&space,&no,task)) isShow = false;
                    }

                }
                //释放内存操作
                if(2 == selectItem)
                {
                    if(1 == option)
                    {
                        //首次适应算法内存释放
                        firstFit_free(head,&no,task);
                    }
                    else
                    {
                        //最佳适应算法内存释放
                        bestFit_free(head,&no,task);
                    }
                }
                //输出当前内存使用情况
                if(isShow) disply(head);
            }

        }

        /*
        *通用算法分配内存
        *return:int
        *SubareaNode:分区链指针
        *int:分区大小指针
        *int:作业号指针
        *int[]:作业号范围指针
        */
        int Fit_alloc(SubareaNode *pSeek,int *spaceSize,
                      int *workNo,int work[])
        {
            //定义分区链指针变量
            SubareaNode *pTemp = NULL;
            //定义是否找到合适的空闲分区标志
            int ret = 0;
            //对符合条件的空闲分区划分内存空间
            while(pSeek)
            {
                //空闲分区状态为未分配
                if(0 == pSeek->state)
                {
                    //-----------核心算法:1-----------
                    if((*spaceSize) == pSeek->size)
                    {
                        //申请内存空间大小与当前分区空间大小一致
                        pSeek->state = 1;
                        pSeek->taskNo = *workNo;
                        ret = 1;
                        break;
                    }
                    if((*spaceSize) < pSeek->size)
                    {
                        //新增加分区作为当前分区划分空间后余下的空闲分区
                        pTemp = new SubareaNode;
                        pTemp->address = (*spaceSize) + pSeek->address;
                        pTemp->next = pSeek->next;
                        pTemp->prior = pSeek;
                        pTemp->size = pSeek->size - (*spaceSize);
                        pTemp->state = 0;
                        pTemp->taskNo = 0;
                        //原分区属性调整
                        pSeek->next = pTemp;
                        pSeek->size = *spaceSize;
                        pSeek->state = 1;
                        pSeek->taskNo = *workNo;
                        //新增分区的下一分区属性调整
                        if(pTemp->next)
                        {
                            pTemp->next->prior = pTemp;
                        }
                        ret = 2;
                        break;
                    }
                    //-----------算法结束-------------
                }
                pSeek = pSeek->next;
            }

            if(ret > 0)
            {
                //记录输入的作业号
                work[(*workNo)-1] = 1;
            }
            else
            {
                cout << "没有找到大小合适的空闲分区,申请失败!" << endl;
            }
            return ret;
        }

        /*
        *首次适应算法分配内存
        *return:bool
        *SubareaNode:分区链指针
        *int:分区大小指针
        *int:作业号指针
        *int[]:作业号范围指针
        */
        bool firstFit_alloc(SubareaNode *pSeek,int *spaceSize,
                      int *workNo,int work[])
        {
            bool flag = false;
            int val =0;
            //对符合条件的空闲分区划分内存空间
            val = Fit_alloc(pSeek,spaceSize,workNo,work);
            if(val > 0) flag = true;
            return flag;

        }

        /*
        *最佳适应算法分配内存
        *return:bool
        *SubareaNode:分区链指针
        *int:分区大小指针
        *int:作业号指针
        *int[]:作业号范围指针
        */
        bool bestFit_alloc(SubareaNode *pbestSeek,int *bestSize,
                      int *bestNo,int bestwork[])
        {
            bool flag = false;
            int val =0;
            //对符合条件的空闲分区划分内存空间
            val = Fit_alloc(pbestSeek,bestSize,bestNo,bestwork);
            //划分完内存空间后需重新按空间大小排序
            if(val == 2) sortNode();
            if(val > 0) flag = true;
            return flag;
        }


        /*
        *首次适应算法回收内存
        *SubareaNode:分区链指针
        *int:作业号指针
        *int[]:作业号范围指针
        */
        void firstFit_free(SubareaNode *pfirstFree,int *FirstNo,int Firstwork[])
        {
            //定义分区链指针变量
            SubareaNode *pCurrently = NULL;
            SubareaNode *pNext = NULL;
            //定义前一个分区空闲标志
            bool previous = false;
            //定义后一个分区空闲标志
            bool next = false;
            while(pfirstFree)
            {
                //-----------核心算法:2-----------
                //寻找作业号所在内存分区
                if((*FirstNo) == pfirstFree->taskNo)
                {
                    //释放分区前一个分区是否空闲
                    if(pfirstFree->prior)
                    {
                        if(0 == pfirstFree->prior->state)
                        {
                             previous = true;
                        }
                    }
                    //释放分区后一个分区是否空闲
                    if(pfirstFree->next)
                    {
                        if(0 == pfirstFree->next->state)
                        {
                             next = true;
                        }
                    }
                    //与前后分区合并
                     if(previous && next)
                    {
                        cout<<"与前后空闲分区合并."<<endl;
                        pCurrently = pfirstFree;
                        pNext = pfirstFree->next;
                        pfirstFree->prior->size = pCurrently->size + pfirstFree->prior->size + pNext->size;
                        pfirstFree->prior->next = pNext->next;
                        pfirstFree->prior->state = 0;
                        pfirstFree->prior->taskNo = 0;
                        //调整前分区新的下一分区前驱指针
                        if(pNext->next) pNext->next->prior = pfirstFree->prior;
                        //释放变量指针
                        delete pCurrently;
                        delete pNext;
                        pCurrently = NULL;
                        pNext = NULL;
                    }
                    //与前分区合并
                    if(previous && !next)
                    {
                        cout<<"与前一个空闲分区合并."<<endl;
                        pCurrently = pfirstFree;
                        pfirstFree->prior->size = pCurrently->size + pfirstFree->prior->size;
                        pfirstFree->prior->next = pCurrently->next;
                        pfirstFree->prior->state = 0;
                        pfirstFree->prior->taskNo = 0;
                        //调整前分区新的下一分区前驱指针
                        if(pCurrently->next) pCurrently->next->prior = pfirstFree->prior;
                        //释放变量指针
                        delete pCurrently;
                        pCurrently = NULL;
                    }
                    //与后分区合并
                    if(!previous && next)
                    {
                        cout<<"与后一个空闲分区合并."<<endl;
                        pNext = pfirstFree->next;
                        //调整当前分区属性
                        pfirstFree->size = pfirstFree->size + pNext->size;
                        pfirstFree->next = pNext->next;
                        pfirstFree->state = 0;
                        pfirstFree->taskNo = 0;
                        //调整当前分区新的下一分区前驱指针
                        if(pfirstFree->next) pfirstFree->next->prior = pfirstFree;
                        //释放变量指针
                        delete pNext;
                        pNext = NULL;
                    }
                    //调整当前分区状态
                    if(!previous && !next)
                    {
                        cout<<"释放当前分区."<<endl;
                        pfirstFree->state = 0;
                        pfirstFree->taskNo = 0;
                    }
                    //调整作业号状态
                    Firstwork[(*FirstNo)-1] = 0;
                    break;
                }
                pfirstFree = pfirstFree->next;
                //-----------算法结束-----------
            }
        }

        /*
        *最佳适应算法回收内存
        *SubareaNode:分区链指针
        *int:作业号指针
        *int[]:作业号范围指针
        */
        void bestFit_free(SubareaNode *pbestFree,int *jobNo,int job[])
        {
            //定义分区链指针变量
            SubareaNode *pPrevious = NULL;
            SubareaNode *pNext = NULL;
            SubareaNode *pfree = pbestFree;
            //定义前一个分区空闲标志
            bool previous = false;
            //定义后一个分区空闲标志
            bool next = false;
            while(pbestFree)
            {
                //-----------核心算法:4-----------
                //寻找作业号所在内存分区
                if((*jobNo) == pbestFree->taskNo)
                {
                    while(pfree)
                    {
                        if(0 == pfree->state)
                        {
                            //释放分区前一个分区是否空闲
                            if(pbestFree->address == (pfree->address + pfree->size))
                            {
                                previous = true;
                                pPrevious = pfree;
                            }
                            //释放分区后一个分区是否空闲
                            if(pfree->address == (pbestFree->address + pbestFree->size))
                            {
                                next = true;
                                pNext = pfree;
                            }
                        }
                        pfree = pfree->next;
                    }
                    //与前后分区合并
                     if(previous && next)
                    {
                        cout<<"与前后空闲分区合并."<<endl;
                        pbestFree->size = pPrevious->size + pbestFree->size + pNext->size;
                        pbestFree->state = 0;
                        pbestFree->taskNo = 0;
                        pbestFree->address = pPrevious->address;
                        //删除前分区
                        deleteNode(pPrevious);
                        deleteNode(pNext);
                        sortNode();
                    }
                    //与前分区或者后分区合并
                    if((previous && !next) || (!previous && next))
                    {
                        if(previous)
                        {
                            cout<<"与前一个空闲分区合并."<<endl;
                            pNext = pPrevious;
                            pbestFree->address = pNext->address;
                        }
                        if(next)
                        {
                            cout<<"与后一个空闲分区合并."<<endl;
                        }
                        //调整当前分区属性
                        pbestFree->size = pbestFree->size + pNext->size;
                        pbestFree->state = 0;
                        pbestFree->taskNo = 0;
                        //删除分区
                        deleteNode(pNext);
                        sortNode();
                    }
                    //调整当前分区状态
                    if(!previous && !next)
                    {
                        cout<<"释放当前分区."<<endl;
                        pbestFree->state = 0;
                        pbestFree->taskNo = 0;
                    }
                    //调整作业号状态
                    job[(*jobNo)-1] = 0;
                    break;
                }
                pbestFree = pbestFree->next;
                //-----------算法结束-----------
            }
        }

        /*
        *删除分区节点
        *SubareaNode:分区链指针
        */
        void deleteNode(SubareaNode *pDel)
        {
            //删除分区
            //如果删除分区是第一节点
            if(NULL == pDel->prior)
            {
                head = pDel->next;
            }
            else
            {
                pDel->prior->next = pDel->next;
            }
            //如果删除分区是最后一节点
            if(NULL == pDel->next)
            {
                pDel->prior->next = NULL;
            }
            else
            {
                pDel->next->prior = pDel->prior;
            }
            //释放变量指针
            delete pDel;
            pDel = NULL;
        }


        /*
        *对空闲分区链表重新按空间大小排序
        */
        void sortNode()
        {
            //定义指针数组保存空闲分区链表指针
            SubareaNode *parr[20];
            //定义数组保存空闲分区的空间大小值
            int arr[20];
            int len = 0;
            SubareaNode *pt = NULL;
            pt = head;
            //--------核心算法3------------
            //采用快速排序算法进行重新排序
            while(pt)
            {
                parr[len] = pt;
                arr[len] = pt->size;
                len++;
                pt = pt->next;
            }
            improved_qsort(parr, arr, 0, len-1);
            //根据数组指针对空闲分区排序
            for(int i=0; i<len; i++)
            {
                //只有一个节点不执行排序
                if(1 == len) break;
                //第一个节点
                if(0 == i)
                {
                    head = parr[i];
                    parr[i]->prior = NULL;
                    parr[i]->next = parr[i+1];
                }
                //最后一个节点
                else if(i == len-1)
                {
                    parr[i]->prior = parr[i-1];
                    parr[i]->next = NULL;
                }
                else
                {
                    parr[i]->prior = parr[i-1];
                    parr[i]->next = parr[i+1];
                }
                //cout << arr[i] <<" 指针="<< parr[i] <<endl;
            }
            //--------算法结束------------
        }

        /*
        *快速排序算法
        *SubareaNode[]:空闲分区链表指针数组
        *int[]:整形数组
        *int:最低数组下标
        *int:最高数组下标
        */
        void improved_qsort(SubareaNode *parr[], int arr[], int low, int high)
        {
            if(low >= high) return;
            int i = low;
            int j = high + 1;
            int pivot = arr[i];
            int temp;
            SubareaNode *ptemp = NULL;
            while(i < j)
            {
                for(i = i + 1; i < high; i++)
                {
                    if(arr[i] >= pivot) break;
                }
                for(j = j - 1; j > low; j--)
                {
                    if(arr[j] <= pivot) break;
                }
                if(i<j)
                {
                    //交换数组中空间大小值
                    temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                    //交换数组指针中的指针
                    ptemp = parr[i];
                    parr[i] = parr[j];
                    parr[j] = ptemp;
                }
            }
            temp = arr[j];
            arr[j] = arr[low];
            arr[low] = temp;

            ptemp = parr[j];
            parr[j] = parr[low];
            parr[low] = ptemp;

            improved_qsort(parr, arr, low, j-1);
            improved_qsort(parr, arr, i, high);
        }

        /*
        *输出内存分区情况
        *SubareaNode:分区链指针
        */
        void disply(SubareaNode *point)
        {
            cout << "++++++++++++++++++++++++++++++++++++++++++++++++++";
            cout << "/n+             当前内存分配情况如下:             +"<<endl;
            cout << "+------------------------------------------------+";
            cout << "/n+  起始地址  |  空间大小  |   状态   |   作业号  +";
            while(point)
            {
                cout << "/n+------------------------------------------------+";
                //输出起始地址
                cout << "/n+  " << int2str(point->address) <<"k  |";
                //输出空间大小
                cout << "  " << int2str(point->size) <<"k  |";
                //输出内存空间使用状态
                if(0 == point->state)
                {
                    cout << "  空  闲  " <<"|";
                }
                else if(1 == point->state)
                {
                    cout << "  已分配  " <<"|";
                }
                else
                {
                    cout << "   "<<point->state<<"    "<<"|";
                }
                //输出作业号
                if(0 == point->taskNo)
                {
                    cout << "           +";
                }
                else
                {
                    cout << "   " <<int2str(point->taskNo) <<" +";
                }
                //cout<<"指针地址="<<point;
                point = point->next;
            }
            cout << "/n++++++++++++++++++++++++++++++++++++++++++++++++++/n";
        }

        /*
        *把整型数字转换成字符串
        *int:整型变量
        */
        string int2str(int num)
        {
            char charTemp[10];
            string strTemp;
            itoa(num, charTemp, 10);
            strTemp = charTemp;
            strTemp.append("        ");
            strTemp = strTemp.substr(0,7);
            return strTemp;
        }
};

int main()
{
    DynamicSubareaAlloction dysuballoc;
    int optionNum = 0;

    while(1)
    {
        //选择分配算法
        cout << "-------------------------";
        cout << "/n请选择一项内存分配算法:";
        cout << "/n 1--首次适应算法";
        cout << "/n 2--最佳适应算法";
        cout << "/n 0--退出程序";
        cout << "/n-------------------------/n";
        do
        {
            cin >> optionNum;
            if(1!= optionNum && 2!= optionNum && 0!= optionNum)
            {
                cout << "输入选项错误,请重新输入!" << endl;
            }
        }while(1!= optionNum && 2!= optionNum && 0!= optionNum);
        //退出程序
        if(0 == optionNum)
        {
            return 0;
        }
        dysuballoc.execAlloction(optionNum);
    }
    return 0;
}

 

源码下载地址

你可能感兴趣的:(算法,String,null,delete,PIVOT,作业)