系統記憶體分配的首次適應演算法和最佳適應演算法連結串列模擬實現
#include<stdlib.h>
using namespace std;
#define Free 0 //空閒狀態
#define Busy 1 //已用狀態
#define OK 1 //完成
#define ERROR 0 //出錯
#define MAX_length 640 //最大記憶體空間為640KB
typedef int Status;
typedef struct freearea//定義一個空閒區說明表結構
{
int ID; //分割槽號
long size; //分割槽大小
long address; //分割槽地址
int state; //狀態
}ElemType;
//---------- 線性表的雙向連結串列儲存結構 ------------
typedef struct DuLNode //double linked list
{
ElemType data;
struct DuLNode *prior; //前趨指標
struct DuLNode *next; //後繼指標
}DuLNode, *DuLinkList;
DuLinkList block_first; //頭結點
DuLinkList block_last; //尾結點
Status alloc(int);//記憶體分配
Status free(int); //記憶體回收
Status First_fit(int, int);//首次適應演算法
Status Best_fit(int, int); //最佳適應演算法
void show();//檢視分配
Status Initblock();//開創空間表
Status Initblock()//開創帶頭結點的記憶體空間連結串列
{
block_first = (DuLinkList)malloc(sizeof(DuLNode));
block_last = (DuLinkList)malloc(sizeof(DuLNode));
block_first->prior = NULL;
block_first->next = block_last;
block_first->data.state = 3;
block_first->data.size = 0;
block_last->prior = block_first;
block_last->next = NULL;
block_last->data.address = 0;
block_last->data.size = MAX_length;
block_last->data.ID = 0;
block_last->data.state = Free;
return OK;
}
//----------------------- 分 配 主 存 -------------------------
Status alloc(int ch)
{
int ID, request;
cout << "請輸入作業(分割槽號(整數)):";
cin >> ID;
cout << "請輸入需要分配的主存大小(單位:KB):";
cin >> request;
if (request<0 || request == 0)
{
cout << "分配大小不合適,請重試!" << endl;
return ERROR;
}
if (ch == 2) //選擇最佳適應演算法
{
if (Best_fit(ID, request) == OK) cout << "分配成功!" << endl;
else cout << "記憶體不足,分配失敗!" << endl;
return OK;
}
else //預設首次適應演算法
{
if (First_fit(ID, request) == OK) cout << "分配成功!" << endl;
else cout << "記憶體不足,分配失敗!" << endl;
return OK;
}
}
//------------------ 首次適應演算法 -----------------------
Status First_fit(int ID, int request)//傳入作業名及申請量
{
DuLNode *p = block_first->next;
//請在此處新增為作業申請新空間且初始化的程式碼
//請在此處完成首次適應演算法的程式碼,分兩種情況:有大小恰好合適的空閒塊和有空閒塊能滿足需求且有剩餘。
//注意函式返回值。
DuLinkList block = (DuLinkList)malloc(sizeof(DuLNode));
memset(block, 0, sizeof(DuLNode));
block->data.ID = ID;
block->data.size = request;
block->data.state = Busy;
while (p)
{
if (p->data.state == Free && p->data.size >= request)
{
if ((p->data.size - request) > 1)
{
block->data.address = p->data.address;
p->data.address = p->data.address + request;
p->data.size = p->data.size - request;
p->prior->next = block;
block->next = p;
block->prior = p->prior;
p->prior = block;
return OK;
}
else
{
p->data.ID = ID;
p->data.state = Busy;
free(block);
return OK;
}
}
p = p->next;
}
free(block);
return ERROR;
}
//-------------------- 最佳適應演算法 ------------------------
Status Best_fit(int ID, int request)
{
//請在此處新增為作業申請新空間且初始化的程式碼
DuLinkList block = (DuLinkList)malloc(sizeof(DuLNode));
memset(block, 0, sizeof(DuLNode));
block->data.ID = ID;
block->data.size = request;
block->data.state = Busy;
DuLNode *p = block_first->next;
DuLNode *q = NULL; //記錄最佳插入位置
int i = 0;
int num = 0;
DuLNode *q1 = NULL;
while (p)
{
if (p->data.state == Free && p->data.size >= request)
{
if (num == 0)
{
q = p;
i = q->data.size - request;
}
else if (p->data.size - request < i)
{
q = p;
i = q->data.size - request;
}
num++;
}
p = p->next;
}
//請在此處完成最佳適應演算法的程式碼,重點:要查詢到最小剩餘空間的分割槽,即最佳插入位置
if (q == NULL) return ERROR;//沒有找到空閒塊
else
{
//請插入找到了最佳位置並實現記憶體分配的程式碼!
if ((q->data.size - request) > 1)
{
block->data.address = q->data.address;
q->data.address = q->data.address + request;
q->data.size = q->data.size - request;
block->next = q;
block->prior = q->prior;
q->prior->next = block;
q->prior = block;
return OK;
}
else
{
q->data.ID = ID;
q->data.state = Busy;
free(block);
return OK;
}
}
}
//----------------------- 主 存 回 收 --------------------
Status free(int ID)
{
DuLNode *p = block_first->next;
DuLNode *p1 = NULL;
while (p)
{
if (p->data.ID == ID)
{
p->data.state = Free;
p->data.ID = Free;
cout << "記憶體塊找到,準備回收!" << endl;
if (p->next == NULL){
if ((p->prior->data.state == Free) && (p->prior->data.address + p->prior->data.size == p->data.address))
{
p->prior->data.size += p->data.size;
p->prior->next = NULL;
free(p);
}
cout << "記憶體塊為最後一塊!" << endl;
break;
}
//請在此處新增其他情況的回收的程式碼,主要包括要回收的分割槽與前面的空閒塊相連或與後面的空閒塊相連,或者與前後空閒塊相連等。
if ((p->next->next == NULL) && (p->next->data.state == Free) && (p->data.address + p->data.size == p->next->data.address))
{
p->data.size += p->next->data.size;
free(p->next);
p->next = NULL;
if ((p->prior->data.state == Free) && (p->prior->data.address + p->prior->data.size == p->data.address))
{
p->prior->data.size += p->data.size;
p->prior->next = NULL;
free(p);
}
break;
}
else if ((p->prior->data.state == Free)&&(p->prior->data.address+p->prior->data.size == p->data.address))
{
if ( p->next->data.state == Free && (p->data.address + p->data.size == p->next->data.address))
{
p1 = p->next;
p->data.size += p->next->data.size;
p->next->next->prior = p;
p->next = p->next->next;
free(p1);
}
p->prior->data.size += p->data.size;
p->prior->next = p->next;
p->next->prior = p->prior;
free(p);
break;
}
else if ((p->next->data.state == Free) && (p->data.address + p->data.size == p->next->data.address))
{
p1 = p->next;
p->data.size += p->next->data.size;
p->next = p->next->next;
p->next->prior = p;
free(p1);
break;
}
break;
}
p = p->next;
}
cout << "回收成功!" << endl;
return OK;
}
//--------------- 顯示主存分配情況 ------------------
void show()
{
cout << "+++++++++++++++++++++++++++++++++++++++\n";
cout << "+++ 主 存 分 配 情 況 +++\n";
cout << "+++++++++++++++++++++++++++++++++++++++\n";
DuLNode *p = block_first->next;
while (p)
{
cout << "分 區 號:";
if (p->data.ID == Free) cout << "Free" << endl;
else cout << p->data.ID << endl;
cout << "起始地址:" << p->data.address << endl;
cout << "分割槽大小:" << p->data.size << " KB" << endl;
cout << "狀 態:";
if (p->data.state == Free) cout << "空 閒" << endl;
else cout << "已分配" << endl;
cout << "——————————————" << endl;
p = p->next;
}
}
//----------------------- 主 函 數---------------------------
void main()
{
int ch;//演算法選擇標記
cout << " 動態分割槽分配方式的模擬 \n";
cout << "************************************\n";
cout << "** 1)首次適應演算法 2)最佳適應演算法 **\n";
cout << "************************************\n";
cout << "請選擇分配演算法:";
cin >> ch;
Initblock(); //開創空間表
int choice; //操作選擇標記
while (1)
{
cout << "********************************************\n";
cout << "** 1: 分配記憶體 2: 回收記憶體 **\n";
cout << "** 3: 檢視分配 0: 退 出 **\n";
cout << "********************************************\n";
cout << "請輸入您的操作 :";
cin >> choice;
if (choice == 1) alloc(ch); // 分配記憶體
else if (choice == 2) // 記憶體回收
{
int ID;
cout << "請輸入您要釋放的分割槽號:";
cin >> ID;
free(ID);
}
else if (choice == 3) show();//顯示主存
else if (choice == 0) break; //退出
else //輸入操作有誤
{
cout << "輸入有誤,請重試!" << endl;
continue;
}
}
}