精华内容
下载资源
问答
  • 文章目录一、固定分区分配1.1数据结构1.2 主函数 一、固定分区分配 1.1数据结构 class MemUsedTable{ // 内存 public: int ID; // 空闲分区的ID int size; // 空闲分区的大小 int address; // 空闲分区的开始...

    要求

    8 、固定式分区分配及可变式分区分配的存储管理方案设计与实现
    【问题描述1】
    设计一个固定式分区分配的存储管理方案,并模拟实现分区的分配和回收过程。
    【设计要求1】
    可以假定每个作业都是批处理作业,并且不允许动态申请内存。为实现分区的分配和回收,可以设定一个分区说明表,按照表中的有关信息进行分配,并根据分区的分配和回收情况修改该表。
    【问题描述2】
    设计一个可变式分区分配的存储管理方案,并模拟实现分区的分配和回收过程。
    【设计要求2】
    对分区的管理法至少是下面三种算法之一:
    ① 首次适应算法
    ② 循环首次适应算法
    ③ 最佳适应算法

    • 首次使用算法,地址由高到低
    • 最佳适应算法,内存空间由最小到大
    • 最坏使用算法,内存空间由大到小

    一、数据结构

    • 建立内存分区链表
    • 建立PCB进程需求链表
    
    class MemUsedTable {   // 内存
    public:
    	int ID;  // 空闲分区的ID
    	int size;  // 空闲分区的大小
    	int address; // 空闲分区的开始地址
    	int state;   // 0 表示未使用, 1表示使用
    	int workID;
    
    	MemUsedTable* next;  // 下一个的指针
    
    	MemUsedTable() {
    		this->ID = 0;
    		this->size = 0;
    		this->address = 0;
    		this->state = 0;   
    		this->workID = 0;
    		this->next = NULL;
    	}
    
    };
    
    
    class PCB {
    	// 进程的数据结构
    public:
    	int ID;  // PCB的ID
    	int size; // PCB需要的内存大小
    	int address; // PCB的开始地址
    	int runState;   // 运行状态  0 表示未获得内存 1 表示获得内存
    	PCB* next;
    
    	PCB() {
    		this->ID = 0;
    		this->size = 0;
    		this->address = 0;
    		this->runState = 0;  // 
    		this->next = NULL;   // 指向下一个
    	}
    
    };
    
    

    一、固定分区分配

    一.1 最佳适应算法

    
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    
    using namespace std;
    
    
    class MemUsedTable {   // 内存
    public:
    	int ID;  // 空闲分区的ID
    	int size;  // 空闲分区的大小
    	int address; // 空闲分区的开始地址
    	int state;   // 0 表示未使用, 1表示使用
    	int workID;
    
    	MemUsedTable* next;  // 下一个的指针
    
    	MemUsedTable() {
    		this->ID = 0;
    		this->size = 0;
    		this->address = 0;
    		this->state = 0;
    		this->workID = 0;
    		this->next = NULL;
    	}
    
    };
    
    
    class PCB {
    	// 进程的数据结构
    public:
    	int ID;  // PCB的ID
    	int size; // PCB需要的内存大小
    	int address; // PCB的开始地址
    	int runState;   // 运行状态  0 表示未获得内存 1 表示获得内存
    	PCB* next;
    
    	PCB() {
    		this->ID = 0;
    		this->size = 0;
    		this->address = 0;
    		this->runState = 0;  //
    		this->next = NULL;   // 指向下一个
    	}
    
    };
    
    void dispMemInfo(MemUsedTable* memReady);    // 展示内存的信息
    void dispPCBInfo(PCB*& pcbQ);         //  展示PCB链表的信息
    
    int getMemLength(MemUsedTable* memReady);   // 获取内存块的长度
    MemUsedTable* inputMem(MemUsedTable* memReady); // 输入固定分区的内存块
    MemUsedTable* sortMem(MemUsedTable* memReady, int flag);   // 对内存进行排序
    
    PCB* inputPCB(PCB* pcbQ);      //  输入PCB块的信息
    MemUsedTable* allocateMem(MemUsedTable*& memReady,
    			  int label, int size);  // 单个内存的分配
    			  
    MemUsedTable* allocateMems(MemUsedTable*& memReady, PCB*& pcbQ); // 对PCB进行分区
    
    bool checkMemEmpty(MemUsedTable* memReady); // 检测内存是否全部释放
    bool checkPCBEmpty(PCB* pcbQ);    // 检测PCB链表是否都在内存中执行
    
    MemUsedTable* recoverMem(MemUsedTable* memReady, PCB* pcbQ);   // 回收内存
    // ============================= //
    
    
    void dispMemInfo(MemUsedTable* memReady) {
    	MemUsedTable* p = memReady;
    
    	cout << endl;
    
    	while (p != NULL) {
    		cout << "MEM->ID: " << p->ID << ", 大小: " << p->size << "B, 分配状态: " << p->state << ", 开始地址:"
    			<< p->address << "B";
    		if (p->workID != 0) {
    			cout << ", 已分配的作业ID: " << p->workID << endl;
    		}
    		else {
    			cout << ", 未分配任何作业" << endl;
    		}
    		p = p->next;
    	}
    
    	cout << endl;
    
    }
    
    
    int getMemLength(MemUsedTable* memReady) {
    	int cnt = 0;
    
    	MemUsedTable* p = memReady;  // NULL 指针
    
    	while (p != NULL) {
    		cnt++;
    		p = p->next;
    	}
    	return cnt;
    }
    
    // 输入内存大小的个数
    MemUsedTable* inputMem(MemUsedTable* memReady) {
    
    	// Notes:参数传入 指针时 不是全局的指针
    
    	/**
    	* 内存的大小以字节为单位
    	*
    	*/
    
    	int address = 0;   // 内存从0开始
    	int id = 0;    //  ID号从0开始
    	MemUsedTable* last = NULL;
    
    	// 输入内存
    	cout << "请输入现有内存的大小:(起始地址从0开始)" << endl;
    	int size;
    	cin >> size;
    
    	int MemSize = pow(2, size);
    
    	cout << "输入的内存的大小为: " << MemSize << "B" << endl;
    
    	// 进行分区,输入分区的块数,以及内存的大小, 2指数倍数
    
    	int num;
    	cout << "输入内存的块数: " << endl;
    	cin >> num;
    
    	for (int i = 0; i < num; ++i) {
    
    		cout << "第" << i << "号" << "内存, 输入内存的大小, 2的指数" << endl;
    		int n;  // 输入占用内存的大小, 2的指数
    		cin >> n;
    		// n 的判断 n 的范围在 0 - MemSize之间
    		int size = pow(2, n);
    
    		while (size >= MemSize) {
    			cout << "输入的n太大, 重新输入!" << endl;
    			cin >> n;
    			size = pow(2, n);
    		}
    
    		cout << "第" << i << "号,内存块的大小为: " << size << "B" << endl << endl;
    
    		MemUsedTable* mp = new MemUsedTable();
    		mp->ID = i;
    		mp->size = size;
    		mp->state = 0;  // 0表示未占用
    		mp->address = address;
    
    		//  调整全局的信息
    		address += size;
    		MemSize -= size;
    
    		// 链接到链表后
    		if (memReady == NULL) {
    			// 没有表格的时候
    			memReady = mp;
    			last = memReady;
    		}
    		else {
    			// 加入链表中
    			last->next = mp;
    			last = mp;
    		}
    
    	}
    	dispMemInfo(memReady);
    	return memReady;
    }
    
    
    MemUsedTable* sortMem(MemUsedTable* memReady, int flag) {
    
    	MemUsedTable* p1 = memReady;
    
    	if (p1 == NULL) {
    		cout << "链表为空" << endl;
    		return NULL;
    	}
    
    
    	if (p1->next == NULL) {
    		cout << "只有一个节点不用排序" << endl;
    		return NULL;
    	}
    
    
    	if (flag == 1) {
    		// 最佳适应算法
    		while (p1->next != NULL) {
    			// 指向下一个
    			MemUsedTable* p2 = p1->next;
    
    			while (p2 != NULL) {
    				if (p1->size > p2->size) {
    					// 交换指针
    	//				MemUsedTable tmp = *p1;
    	//				*p1 = *p2;
    	//				*p2 = temp;
    	//
    	//				tmp.next = p1;
    	//				p1->next = p2->next;
    	//				p2->next = tmp.next;
    
    					int ID = p1->ID;
    					int size = p1->size;
    					int address = p1->address;
    					int workID = p1->workID;
    					int state = p1->state;
    
    					p1->ID = p2->ID;
    					p1->size = p2->size;
    					p1->address = p2->address;
    					p1->workID = p2->workID;
    					p1->state = p2->state;
    
    					p2->ID = ID;
    					p2->size = size;
    					p2->address = address;
    					p2->workID = workID;
    					p2->state = state;
    
    				}
    
    				p2 = p2->next;
    			}
    			p1 = p1->next;
    		}
    		return memReady;
    	}
    
    	else if (flag == 2) {
    		// 最坏适应算法
    		while (p1->next != NULL) {
    			// 指向下一个
    			MemUsedTable* p2 = p1->next;
    
    			while (p2 != NULL) {
    				if (p1->size < p2->size) {
    					// 交换指针
    	//				MemUsedTable tmp = *p1;
    	//				*p1 = *p2;
    	//				*p2 = temp;
    	//
    	//				tmp.next = p1;
    	//				p1->next = p2->next;
    	//				p2->next = tmp.next;
    
    					int ID = p1->ID;
    					int size = p1->size;
    					int address = p1->address;
    					int workID = p1->workID;
    					int state = p1->state;
    
    					p1->ID = p2->ID;
    					p1->size = p2->size;
    					p1->address = p2->address;
    					p1->workID = p2->workID;
    					p1->state = p2->state;
    
    					p2->ID = ID;
    					p2->size = size;
    					p2->address = address;
    					p2->workID = workID;
    					p2->state = state;
    
    				}
    
    				p2 = p2->next;
    			}
    			p1 = p1->next;
    		}
    
    		return memReady;
    	}
    
    	else if (flag == 3) {
    		// 首次使用算法, 不排序
    		return memReady;
    	}
    }
    
    void dispPCBInfo(PCB*& pcbQ) {
    	PCB* p = pcbQ;
    
    	cout << endl;
    
    	while (p != NULL) {
    		cout << "PCB->ID: " << p->ID << ", PCB运行状态: " << p->runState << ", PCB大小: " <<
    			 p->size << "B, " << ", PCB运行地址: " << p->address << endl;
    		p = p->next;
    	}
    
    	cout << endl;
    
    }
    
    PCB* inputPCB(PCB* pcbQ) {
    	/**
    	* 作业不排序
    	*/
    	cout << "输入作业的个数" << endl;
    
    	int num;
    	PCB* last = NULL;
    	cin >> num;
    
    	for (int i = 1; i <= num; ++i) {
    		PCB* np = new PCB();
    		np->ID = i;
    
    		cout << "输入PCB的大小" << endl;
    
    		int pcbSize;
    		cin >> pcbSize;
    
    		np->size = pcbSize;
    
    		if (pcbQ == NULL) {
    			pcbQ = np;
    			last = pcbQ;
    		}
    		else {
    			last->next = np;
    			last = np;
    		}
    	}
    
    	return pcbQ;
    
    }
    
    
    MemUsedTable* allocateMem(MemUsedTable*& memReady, int label, int size) {
    	/**
    	* 分配内存给作业 label 为作业号, size为分配内存的大小
    	*/
    
    	MemUsedTable* p = memReady;
    
    	while (p != NULL) {
    		if (p->size >= size) {
    
    			if (p->state != 1) {
    				p->state = 1;
    				p->workID = label;
    				return p;
    			}
    		}
    
    		p = p->next;
    	}
    	return NULL;
    
    }
    
    
    MemUsedTable* allocateMems(MemUsedTable*& memReady, PCB*& pcbQ) {
    	/**
    	* 1. 循环作业进行分配
    	* 2. 修改信息
    	*/
    	PCB* p = pcbQ;
    
    	while (p != NULL) {
    
    		if (p->runState != 1) {
    			MemUsedTable* allocated_mem = allocateMem(memReady, p->ID, p->size);
    
    			if (allocated_mem != NULL) {
    				cout << "分配成功: PCB_ID: " << p->ID << " 分配的内存块ID: " << allocated_mem->ID << endl;
    				p->runState = 1;
    				p->address = allocated_mem->address;
    
    			}
    		}
    		p = p->next;
    
    	}
    	return memReady;
    
    }
    
    bool checkMemEmpty(MemUsedTable* memReady) {
    	MemUsedTable* p = memReady;
    
    	bool flag = true;    // 假设内存已经全部释放
    
    	while (p != NULL) {
    		if (p->state == 1) {
    			return false;
    		}
    
    		p = p->next;
    
    	}
    	return flag;
    
    }
    
    bool checkPCBEmpty(PCB* pcbQ) {
    	PCB* p = pcbQ;
    
    	while (p != NULL) {
    		if (p->runState == 0) {
    			return false;
    		}
    		p = p->next;
    	}
    
    	return true;
    }
    
    MemUsedTable* recoverMem(MemUsedTable* memReady, PCB* pcbQ) {
    	/**
    	* 收回固定分配的内存
    	* 输入要收回分区的个数,输入要收回分区的ID号,
    	* 根据ID号释放内存, 更改内存块的状态
    	*
    	*/
    	int num;
    
    	int memLength = getMemLength(memReady);
    
    	while (1) {
    
    		cout << endl << endl;
    
    		dispMemInfo(memReady);
    
    		cout << "输入要释放的内存块号" << endl;
    		int memBlock;
    		cin >> memBlock;
    
    		if (checkPCBEmpty(pcbQ) && checkMemEmpty(memReady)) {
    			cout << "作业已经调度完, 并且内存以释放完" << endl;
    			dispPCBInfo(pcbQ);
    			break;
    		}
    
    		MemUsedTable* p = memReady;
    
    
    		while (p != NULL) {
    			if (p->ID == memBlock) {
    				if (p->state == 1) {
    					p->state = 0;   // 释放内存
    					p->workID = 0;   // 修改被占用的工作块
    					cout << "内存释放成功" << endl;
    					allocateMems(memReady, pcbQ);
    					dispMemInfo(memReady);
    					dispPCBInfo(pcbQ);
    				}
    				else if (p->state == 0) {
    					cout << "此内存块为空闲块" << endl;
    				}
    			}
    			p = p->next;
    		}
    
    		if (checkPCBEmpty(pcbQ) && checkMemEmpty(memReady)) {
    			cout << "作业已经调度完, 并且内存以释放完" << endl;
    			dispPCBInfo(pcbQ);
    			break;
    		}
    
    
    		char flag;
    		cout << "是否继续释放内存 y/Y ->Yes, n/N ->No" << endl;
    		cin >> flag;
    
    		while (!(flag == 'Y' || flag == 'y' || flag == 'N' || flag == 'n')) {
    			cout << "输入 y/Y ->Yes, n/N ->No" << endl;
    			cin >> flag;
    		}
    
    		if (flag == 'y' || flag == 'Y') {
    			continue;
    		}
    		else if (flag == 'N' || flag == 'n') {
    			break;
    		}
    	}
    
    	cout << endl << "内存状态: " << endl;
    	dispMemInfo(memReady);
    	return memReady;
    
    }
    
    
    
    int main() {
    	cout << "<<<<<<<<<<<<<<<<<<<<<< 固定分区, 最佳适应算法算法 >>>>>>>>>>>>>>>>>>>>>>>>>>>>" << endl;
    
    	MemUsedTable* memReady = NULL;  // 内存链表
    
    	MemUsedTable* mem = inputMem(memReady);
    
    	MemUsedTable* sortmem = sortMem(mem, 1);
    
    	PCB* pcbQ = NULL;
    
    	PCB* input_pcb = inputPCB(pcbQ);
    
    	dispPCBInfo(input_pcb);
    
    	allocateMems(sortmem, input_pcb);
    
    	dispPCBInfo(input_pcb);
    
    	recoverMem(sortmem, input_pcb);
    
    	system("pause");
    
    	return 0;
    }
    
    
    /**
    测试  Case : 1
    10
    4
    5
    6
    5
    4
    6
    20
    10
    20
    20
    30
    20
    
    */
    
    
    
    

    二、可变分区分配方式

    二、1 可变分区-最佳适应算法

    
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    
    using namespace std;
    
    
    class MemUsedTable {   // 内存
    public:
    	int ID;  // 空闲分区的ID
    	int size;  // 空闲分区的大小
    	int address; // 空闲分区的开始地址
    	int state;   // 分区的状态 0 未分配 1 分配
    	int workID;
    	MemUsedTable* pre;   // 前一个指针
    	MemUsedTable* next;  // 下一个指针
    
    	MemUsedTable() {
    		this->ID = 0;
    		this->size = 0;
    		this->address = 0;
    		this->state = 0;  // 未使用
    		this->workID = 0;
    		this->next = NULL;
    		this->pre = NULL;
    	}
    
    };
    
    
    class PCB {
    	// 进程的数据结构
    public:
    	int ID;  // PCB的ID
    	int size; // PCB需要的内存大小
    	int address; // PCB的开始地址
    	int runState;   // 运行状态
    	PCB* next;
    
    	PCB() {
    		this->ID = 0;
    		this->size = 0;
    		this->address = -1;
    		this->runState = 0;  // 0 未运行 1 运行
    		this->next = NULL;   // 指向下一个
    	}
    
    };
    
    void dispMemInfo(MemUsedTable* memReady); // 展示内存块的信息
    void dispPCBInfo(PCB*& pcbQ);    // 展示PCB进程的信息
    
    int getMemLength(MemUsedTable* memReady); // 获取内存块的长度,可用于内存划分
    MemUsedTable* inputMem(MemUsedTable* memReady); // 输入内存的大小
    PCB* inputPCB(PCB* pcbQ);         // 输入进程PCB的信息,PCB的大小
    MemUsedTable* sortMem(MemUsedTable* memReady, int flag);  // 对内存按照要求排序
                                             // 1 最佳适应 2 最坏适应, 3 首次适应
    bool checkMemEmpty(MemUsedTable* memReady);     // 检测内存块是否都未被使用
    bool checkPCBEmpty(PCB* pcbQ);          // 检测内存都已经得到分配,并且运行
    MemUsedTable* allocateMem(MemUsedTable*& memReady, int label, int size);
    												   // 分配单个进程PCB
    												   
    MemUsedTable* allocateMems(MemUsedTable*& memReady, PCB*& pcbQ); // 对PCB链表进行内存分配
    
    MemUsedTable* recoverMem(MemUsedTable* memReady, PCB* pcbQ);   // 回收内存
    
    ///====================================
    
    
    void dispMemInfo(MemUsedTable* memReady) {
    	MemUsedTable* p = memReady;
    
    	cout << endl;
    
    	while (p != NULL) {
    		cout << "Mem->ID: " << p->ID << ", 大小: " << p->size << "B, 分配状态: " << p->state << ", 开始地址:"
    			<< p->address << "B";
    		if (p->workID != 0) {
    			cout << ", 已分配的作业ID: " << p->workID << endl;
    		}
    		else {
    			cout << ", 未分配任何作业" << endl;
    		}
    		p = p->next;
    	}
    
    	cout << endl;
    
    }
    
    int getMemLength(MemUsedTable* memReady) {
    	int cnt = 0;
    
    	MemUsedTable* p1 = memReady;  // NULL 指针
    
    	// 链表为空的时候
    	if (p1 == NULL) {
    		cout << "链表为空" << endl;
    		return 0;
    	}
    
    	while (p1 != NULL) {
    		cnt++;
    		p1 = p1->next;
    	}
    
    	return cnt;
    }
    
    // 输入内存大小的个数
    MemUsedTable* inputMem(MemUsedTable* memReady) {
    
    	// 输入内存
    	cout << "请输入现有内存的大小:(起始地址从0开始)" << endl;
    	int size;
    	cin >> size;
    
    	int MemSize = pow(2, size);
    
    	// 建立主内存块
    	MemUsedTable* mp = new MemUsedTable();
    	mp->ID = 0;
    	mp->size = MemSize;
    	mp->state = 0;  // 0表示未占用
    	mp->address = 0;
    
    	memReady = mp;
    
    	cout << "输入的内存的大小为: " << MemSize << "B" << endl;
    
    	//	dispMemInfo(memReady);
    	return memReady;
    }
    
    void dispPCBInfo(PCB*& pcbQ) {
    	PCB* p = pcbQ;
    
    	cout << endl;
    
    	while (p != NULL) {
    		cout << "PCB->ID: " << p->ID << ", PCB运行状态: " << p->runState << ", PCB大小: " <<
    			p->size << "B, " << ", PCB运行地址: " << p->address << endl;
    		p = p->next;
    	}
    
    	cout << endl;
    
    }
    
    PCB* inputPCB(PCB* pcbQ) {
    	/**
    	* 作业不排序
    	*/
    	cout << "输入作业的个数" << endl;
    
    	int num;
    	PCB* last = NULL;
    	cin >> num;
    
    	for (int i = 1; i <= num; ++i) {
    		PCB* np = new PCB();
    		np->ID = i;
    
    		cout << "输入PCB的大小" << endl;
    
    		int pcbSize;
    		cin >> pcbSize;
    
    		np->size = pcbSize;
    
    		if (pcbQ == NULL) {
    			pcbQ = np;
    			last = pcbQ;
    		}
    		else {
    			last->next = np;
    			last = np;
    		}
    	}
    
    	return pcbQ;
    
    }
    
    MemUsedTable* sortMem(MemUsedTable* memReady, int flag) {
    
    	MemUsedTable* p1 = memReady;
    
    	if (p1 == NULL) {
    		cout << "链表为空" << endl;
    		return NULL;
    	}
    
    
    	if (p1->next == NULL) {
    		cout << "只有一个节点不用排序" << endl;
    		return memReady;
    	}
    
    
    	if (flag == 1) {
    		// 最佳适应算法
    		while (p1->next != NULL) {
    			// 指向下一个
    			MemUsedTable* p2 = p1->next;
    
    			while (p2 != NULL) {
    				if (p1->size > p2->size) {
    					// 交换指针
    	//				MemUsedTable tmp = *p1;
    	//				*p1 = *p2;
    	//				*p2 = temp;
    	//
    	//				tmp.next = p1;
    	//				p1->next = p2->next;
    	//				p2->next = tmp.next;
    
    					int ID = p1->ID;
    					int size = p1->size;
    					int address = p1->address;
    					int workID = p1->workID;
    					int state = p1->state;
    
    					p1->ID = p2->ID;
    					p1->size = p2->size;
    					p1->address = p2->address;
    					p1->workID = p2->workID;
    					p1->state = p2->state;
    
    					p2->ID = ID;
    					p2->size = size;
    					p2->address = address;
    					p2->workID = workID;
    					p2->state = state;
    
    				}
    
    				p2 = p2->next;
    			}
    			p1 = p1->next;
    		}
    		return memReady;
    	}
    
    	else if (flag == 2) {
    		// 最坏适应算法
    		while (p1->next != NULL) {
    			// 指向下一个
    			MemUsedTable* p2 = p1->next;
    
    			while (p2 != NULL) {
    				if (p1->size < p2->size) {
    					// 交换指针
    	//				MemUsedTable tmp = *p1;
    	//				*p1 = *p2;
    	//				*p2 = temp;
    	//
    	//				tmp.next = p1;
    	//				p1->next = p2->next;
    	//				p2->next = tmp.next;
    
    					int ID = p1->ID;
    					int size = p1->size;
    					int address = p1->address;
    					int workID = p1->workID;
    					int state = p1->state;
    
    					p1->ID = p2->ID;
    					p1->size = p2->size;
    					p1->address = p2->address;
    					p1->workID = p2->workID;
    					p1->state = p2->state;
    
    					p2->ID = ID;
    					p2->size = size;
    					p2->address = address;
    					p2->workID = workID;
    					p2->state = state;
    
    				}
    
    				p2 = p2->next;
    			}
    			p1 = p1->next;
    		}
    
    		return memReady;
    	}
    
    	else if (flag == 3) {
    		// 首次使用算法, 不排序
    		return memReady;
    	}
    }
    
    bool checkMemEmpty(MemUsedTable* memReady) {
    	MemUsedTable* p = memReady;
    
    	bool flag = true;    // 假设内存已经全部释放
    
    	while (p != NULL) {
    		if (p->state == 1) {
    			return false;
    		}
    
    		p = p->next;
    
    	}
    	return flag;
    
    }
    
    bool checkPCBEmpty(PCB* pcbQ) {
    	PCB* p = pcbQ;
    
    	while (p != NULL) {
    		if (p->runState == 0) {
    			return false;
    		}
    		p = p->next;
    	}
    
    	return true;
    }
    
    
    MemUsedTable* allocateMem(MemUsedTable*& memReady, int label, int size) {
    	/**
    	* 分配内存给作业 label 为作业号, size为分配内存的大小
    	*/
    
    	MemUsedTable* p = memReady;
    
    	while (p != NULL) {
    
    		if (p->size >= size) {
    			// 未被占用
    			if (p->state != 1) {
    				p->state = 1;
    				p->workID = label;
    
    				// 割掉一个分区
    				if (p->size > size) {
    					MemUsedTable* mp = new MemUsedTable();
    					int ID = getMemLength(memReady);
    
    					int splitSize = p->size - size;
    					int address = p->address + size;
    
    					// 修改分区信息
    					mp->ID = ID;
    					mp->size = splitSize;
    					mp->address = address;
    					mp->state = 0;
    					mp->workID = 0;
    
    					// 添加到链表中
    					if (p->next != NULL) {
    						MemUsedTable* nextP = p->next;
    						mp->pre = p;
    						p->next = mp;
    
    						nextP->pre = mp;
    						mp->next = nextP;
    					}
    					else {
    						// 只有一个分区的时候与
    						p->next = mp;
    						mp->pre = p;
    					}
    
    				}
    
    				// 修改p的状态
    				p->size = size;
    
    				return p;
    			}
    
    		}
    
    		p = p->next;
    	}
    	return NULL;
    
    }
    
    MemUsedTable* allocateMems(MemUsedTable*& memReady, PCB*& pcbQ) {
    
    	PCB* p = pcbQ;
    
    	while (p != NULL) {
    
    		if (p->runState != 1) {
    			MemUsedTable* allocated_mem = allocateMem(memReady, p->ID, p->size);
    
    			if (allocated_mem != NULL) {
    				cout << "分配成功: PCB_ID: " << p->ID << " 分配的内存块ID: " << allocated_mem->ID << endl;
    				p->runState = 1;
    				p->address = allocated_mem->address;
    
    			}
    		}
    		p = p->next;
    
    	}
    	return memReady;
    }
    
    MemUsedTable* recoverMem(MemUsedTable* memReady, PCB* pcbQ) {
    	/**
    	* 动态回收内存
    	* 输入要释放内存的个数
    	* 动态回收的情形
    	*   1. 上一个是空闲分区, 与上一个合并,开始的地址为上一个空闲分区
    	*   2. 下一个是空闲分区, 与下一个合并,开始的地址为这个内存区的地址
    	*   3. 上一个与下一个都是空闲分区, 与上下合并,内存分区减少一个, 开始第一位号小的那个
    	*   4. 没有相邻的时候, 放到队列中
    	*/
    
    
    
    	while (1) {
    
    		int memLength = getMemLength(memReady);
    
    		cout << endl << endl;
    
    		dispMemInfo(memReady);
    
    		// 检查内存为空
    		if (checkPCBEmpty(pcbQ) && checkMemEmpty(memReady)) {
    			cout << "作业已经调度完, 并且内存以释放完" << endl;
    			dispPCBInfo(pcbQ);
    			break;
    		}
    
    		cout << "输入要释放的内存块号" << endl;
    		int memBlock;
    		cin >> memBlock;
    
    
    
    		while (memBlock >= memLength) {
    			cout << "内存块号越界!, 请重新输入" << endl;
    			cin >> memBlock;
    		}
    
    		MemUsedTable* p = memReady;
    
    		while (p != NULL) {
    			if (p->ID == memBlock) {
    				if (p->state == 1) {
    
    					// 判断前后分区
    					if (p->pre != NULL && p->next != NULL) {
    						if (p->pre->state == 0 && p->next->state == 0) {
    							// 前后分区空闲
    
    							cout << endl << "前为空,后为空" << endl << endl;
    							// 修改信息
    							p->pre->size += p->size + p->next->size;
    
    							// 确定地址
    							int addressPre = p->pre->address;
    							int addressCurrent = p->address;
    							int addressNext = p->next->address;
    
    							int min = addressPre > addressCurrent ? addressCurrent : addressPre;
    							min = min < addressNext ? min : addressNext;
    
    							p->pre->address = min;
    
    							// 指针移动 三个分区合并
    							p->pre->next = p->next->next;
    
    							if (p->next->next != NULL) {
    								p->next->next->pre = p->pre;
    							}
    
    							// delete p->next;
    							// delete p;
    
    						}
    						else if (p->pre->state == 0 && p->next->state == 1) {
    							// 前一个空闲
    							cout << endl << "前为空,后不为空" << endl << endl;
    
    							p->pre->size += p->size;
    							p->pre->address = p->size > p->pre->address ? p->pre->size : p->address;
    
    							// 修改指针
    							p->pre->next = p->next;
    							p->next->pre = p->pre;
    							// delete p;
    
    						}
    						else if (p->pre->state == 1 && p->next->state == 0) {
    
    							cout << endl << "前不为空,后为空" << endl << endl;
    
    							// 修改状态
    							p->size += p->next->size;
    							p->address = p->address < p->next->address ? p->address : p->next->address;
    
    							p->state = 0;
    							p->workID = 0;
    
    							// 从后指向前, 在从前指向后
    
    							// 修改指针
    							if (p->next->next != NULL) {
    
    								p->next->next->pre = p;
    								// p->next->pre = NULL;
    
    								p->next = p->next->next;
    								// p->next->next  = NULL;
    
    							}
    
    							// 后面的内存只有一个的时候
    							if (p->next->next == NULL) {
    								p->next = NULL;
    							}
    
    
    							// delete p->next;
    
    						}
    						else if (p->pre->state == 1 && p->next->state == 1) {
    
    							cout << endl << "前不为空,后不为空" << endl << endl;
    
    							p->state = 0;
    							p->workID = 0;
    						}
    					}
    
    					else if (p->pre == NULL && p->next != NULL) {
    						if (p->next->state == 0) {
    
    							cout << endl << "前为NULL, 后为空" << endl << endl;
    
    							// 修改状态
    							p->size += p->next->size;
    							p->address = p->address < p->next->address ? p->address : p->next->address;
    
    							p->state = 0;
    							p->workID = 0;
    
    							// 修改指针
    							if (p->next->next != NULL) {
    
    								p->next->next->pre = p;
    								// p->next->pre = NULL;
    
    								p->next = p->next->next;
    								// p->next->next  = NULL;
    
    							}
    
    							// MemUsedTable* tmp = p->next;
    
    							// 后面的内存只有一个的时候
    							if (p->next->next == NULL) {
    								p->next = NULL;
    							}
    
    							// delete tmp;
    
    						}
    						else {
    							cout << endl << "前为NULL, 后不为空" << endl << endl;
    							p->state = 0;
    							p->workID = 0;
    
    						}
    					}
    
    					else if (p->next == NULL && p->pre != NULL) {
    						if (p->pre->state == 0) {
    
    							cout << endl << "前为空,后为NULL" << endl << endl;
    
    							p->pre->size += p->size;
    							p->pre->address = p->size > p->pre->address ? p->pre->size : p->address;
    
    							// 移动指针
    							p->pre->next = p->next;  // 为NULL
    
    							// delete p;
    						}
    						else {
    							cout << endl << "前不为空,后为NULL" << endl << endl;
    
    							p->state = 0;
    							p->workID = 0;
    
    						}
    					}
    
    					cout << "内存释放成功" << endl;
    					// 释放完之后 再次分配
    
    					MemUsedTable* sortedMem = sortMem(memReady, 1);
    
    					dispMemInfo(sortedMem);
    					dispPCBInfo(pcbQ);
    					allocateMems(sortedMem, pcbQ);
    					dispMemInfo(sortedMem);
    					dispPCBInfo(pcbQ);
    				}
    				else if (p->state == 0) {
    					cout << "此内存块为空闲块" << endl;
    				}
    
    				break;
    			}
    
    			p = p->next;
    		}
    
    		// 检查内存为空
    
    		if (checkPCBEmpty(pcbQ) && checkMemEmpty(memReady)) {
    			cout << "作业已经调度完, 并且内存以释放完" << endl;
    			dispPCBInfo(pcbQ);
    			break;
    		}
    
    		// 合法的输入
    		char flag;
    		cout << "是否继续释放内存 y/Y ->Yes, n/N ->No" << endl;
    		cin >> flag;
    
    		while (!(flag == 'Y' || flag == 'y' || flag == 'N' || flag == 'n')) {
    			cout << "输入 y/Y ->Yes, n/N ->No" << endl;
    			cin >> flag;
    		}
    
    		if (flag == 'y' || flag == 'Y') {
    			continue;
    		}
    		else if (flag == 'N' || flag == 'n') {
    			break;
    		}
    	}
    
    	// 最后展示内存的状态
    	cout << endl << "内存状态: " << endl;
    	dispMemInfo(memReady);
    	return memReady;
    
    }
    
    
    int main() {
    
    	MemUsedTable* memReady = NULL;
    
    	MemUsedTable* mem = inputMem(memReady);
    
    	dispMemInfo(mem);
    
    	PCB* pcbQ = NULL;
    
    	pcbQ = inputPCB(pcbQ);
    
    	dispPCBInfo(pcbQ);
    
    	MemUsedTable* allocate_mem = allocateMems(mem, pcbQ);
    
    	dispMemInfo(allocate_mem);
    	dispPCBInfo(pcbQ);
    
    	recoverMem(allocate_mem, pcbQ);
    
    	return 0;
    }
    
    
    /**
    
    测试 Case1 :
    7
    3
    50
    60
    30
    
    */
    
    
    展开全文
  • /*实验四-内存管理之固定分区分配算法思想:预先将内存空间划分成若干个空闲分区,分配过程根据用户需求将某一个满足条件的分区直接分配(不进行分割),作业完成后回收对应内存。整个分配过程分区大小和个数不发生...

    /*实验四-内存管理之固定分区分配

    算法思想:

    预先将内存空间划分成若干个空闲分区,

    分配过程根据用户需求将某一个满足条件的分区直接分配

    (不进行分割),作业完成后回收对应内存。

    整个分配过程分区大小和个数不发生变化。*/#include#include#include

    using namespacestd;#define getpch(type) (type*)malloc(sizeof(type))

    int SIZE;//内存的大小

    struct node//内存分区使用说明表

    {int id;//内存块的id;

    int size;//内存块的大小

    int begin_adress;//内存块的起始地址

    char status;F-已分配,T-未分配

    struct node *next;

    }*p,*ready=NULL;

    typedefstructnode SIF;void InitMemory();//初始化固定内存的设置

    void showinfo();//打印分配的情况

    void recover();//作业完成后回收资源

    void allocation();//给作业分配空间

    int allocate(int size);//分配内存,返回0代表分配成功

    intmain()

    {intcommand;

    InitMemory();//初始化内存说明表

    printf("\n 请输入命令,给作业分配资源输入1,释放资源输入2,退出请输入任意键:\n");

    scanf("%d",&command);while(1){if(command==1)

    allocation();else if(command==2)

    recover();else

    break;

    printf("\n 请继续输入命令 \n");

    scanf("%d",&command);

    }return 0;

    }void showinfo()//打印内存分配情况

    {

    printf("\n 当前内存分配情况如下:\n");

    printf("\n===id===size===begin_adress===status \n");

    p=ready;while(p!=NULL)

    {

    printf("\n %d %d %d %c\n",p->id,p->size,p->begin_adress,p->status);

    p=p->next;

    }

    }void InitMemory()//初始化内存表

    {int num,i,j,d=0,id=0;

    SIF*last=ready;

    printf("\n 请输入现有内存的大小: (起始地址从0开始) \n");

    scanf("%d",&SIZE);//初始化内存信息

    printf("\n 请输入固定分区内存块的个数:");

    scanf("%d",&num);for(i=0; i

    {intn;

    printf("\n 请输入内存块%d的大小(KB):",i);

    scanf("%d",&n);for(j=0; j

    {

    p=getpch(SIF);//#define getpch(type) (type*)malloc(sizeof(type))

    p->id=id++;

    p->size=(int)(pow(2,4+i));//size是按照2的指数递增的

    p->begin_adress=d;if(p->status==NULL)//是否被分配初始化

    p->status='T';elsep->status='F';

    p->next=NULL;

    d+=p->size;if(d>=SIZE)

    {

    printf("\n 已超出系统总内存量,%d号分配失败 \n",p->id);break;

    }if(ready==NULL)

    {

    ready=p;

    last=ready;

    }else{

    last->next=p;

    last=last->next;

    }

    }

    }

    showinfo();

    }void allocation()//给作业分配空间

    {intnum1;inti,s;//给作业分配内存空间

    printf("\n 请输入待分配内存的作业个数:");

    scanf("%d",&num1);for(i=0; i

    printf("\n 请输入第%d个作业的大小:",i);

    scanf("%d",&s);if(allocate(s)==1){

    printf("\n 已为该作业分配内存空间\n");

    printf("\n 存储该作业内存空间的详细信息如下:\n");

    printf("\n 内存块号:%d, 内存大小:%d \n",p->id,p->size);

    }elseprintf("\n 未能该该作业分配内存 \n");

    }

    showinfo();

    }void recover()//作业完成后回收资源

    {inti,k,num;

    printf("\n 请输入需要释放的作业个数:");

    scanf("%d",&num);for(i=0; i

    printf("\n 请输入存储该作业的内存分区说明表的ID \n");

    scanf("%d",&k);

    p=ready;while(p!=NULL){if(p->id==k){

    p->status='T';

    printf("\n 已释放该作业所占用的资源 \n");break;

    }

    p=p->next;

    }

    }

    showinfo();//完成作业后回收内存空间

    }int allocate(int size)//分配内存,返回0代表分配成功

    {

    p=ready;while(p!=NULL)

    {if((p->status=='T')&&(p->size>=size))

    {

    p->status='F';return 1;

    }

    p=p->next;

    }return 0;

    }

    展开全文
  • 本实验通过三种分区分配的方法,分别是固定分区分配、可变分区分配及段页式分区分配,从连续内存分区分配方式到离散分区分配方式。段页式的采用减少了碎片的产生,极大地提高了内存空间的利用率,但是却增加了访存的...

           本实验通过三种分区分配的方法,分别是固定分区分配、可变分区分配及段页式分区分配,从连续内存分区分配方式到离散分区分配方式。段页式的采用减少了碎片的产生,极大地提高了内存空间的利用率,但是却增加了访存的次数,因此,可以采用快表机制,减少访存的次数,对段页式存储管理进行优化。

          1、固定分区分配回收内存空间代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    #define getpch(type) (type*)malloc(sizeof(type))
    int SIZE;
    struct sif //内存分区使用说明表
    {
        int id;
        int size;
        int begin_adress;
        char status;//F-已分配,T-未分配
        struct sif *next;
    }*p,*ready=NULL;
    
    typedef struct sif SIF;
    
    int allocate(int size)//分配内存,返回0代表分配成功
    {
        p=ready;
        while(p!=NULL)
        {
            if((p->status=='T')&&(p->size>=size))
            {
                p->status='F';
                return 1;
            }
            p=p->next;
        }
        return 0;
    }
    void disp()//打印内存分配情况
    {
        printf("\n 当前内存分配情况如下:\n");
        printf("\n |id |size |begin_adress |status \n");
        p=ready;
        while(p!=NULL)
        {
            printf("\n %d| %d| %d| %c\n",p->id,p->size,p->begin_adress,p->status);
            p=p->next;
        }
    }
    void Input()
    {
        int num,i,j,d=0,id=0;
        SIF *last=ready;
        printf("\n 请输入现有内存的大小:  (起始地址从0开始) \n");
        scanf("%d",&SIZE);
        //初始化内存信息
        printf("\n 请输入固定分区不同内存块的个数: ");
        scanf("%d",&num);
        for(i=0; i<num; i++)
        {
            int n;
            printf("\n 请输入%f KB内存的个数: ",pow(2,4+i));
            scanf("%d",&n);
            for(j=0; j<n; j++)
            {
                p=getpch(SIF);
                p->id=id++;
                p->size=(int)(pow(2,4+i));//size是按照2的指数递增的
                p->begin_adress=d;
                if((rand()%2)==0)//是否被分配初始化
                    p->status='T';
                else
                    p->status='F';
                p->next=NULL;
                d+=p->size;
                if(d>=SIZE)
                {
                  printf("\n 已超出系统总内存量,%d号分配失败 \n",p->id);
                  break;
                }
                if(ready==NULL)
                {
                    ready=p;
                    last=ready;
                }
                else
                {
                    last->next=p;
                    last=last->next;
                }
            }
        }
        disp();//打印内存说明表
    }
    void allocation()
    {
        int num1;
        int i,s;
        //给作业分配内存空间
        printf("\n 请输入待分配内存的作业个数:");
    
    
        scanf("%d",&num1);
        for(i=0; i<num1; i++)
        {
            printf("\n 请输入第%d个作业的大小: ",i);
            scanf("%d",&s);
            if(allocate(s)==1)
            {
                printf("\n 已为该作业分配内存空间\n");
                printf("\n 存储该作业内存空间的详细信息如下:\n");
                printf("\n 内存块号:%d, 内存大小:%d \n",p->id,p->size);
            }
            else
                printf("\n 未能该该作业分配内存 \n");
        }
        disp();
    }
    void recover()//作业完成后回收资源
    {
        int i,k,num;
        printf("\n 请输入需要释放的作业个数: ");
        scanf("%d",&num);
        for(i=0; i<num; i++)
        {
            printf("\n 请输入存储该作业的内存分区说明表的ID \n");
            scanf("%d",&k);
            p=ready;
            while(p!=NULL)
            {
                if(p->id==k)
                {
                    p->status='T';
                    printf("\n 已释放该作业所占用的资源 \n");
                    break;
                }
                p=p->next;
            }
        }
        disp();
    }
    int main()
    {
        int command;
        Input();//初始化内存说明表
        printf("\n 请输入命令,给作业分配资源输入1,释放资源输入2,退出请输入任意键:\n");
        scanf("%d",&command);
        while(1)
        {
            if(command==1)
                allocation();
            else if(command==2)
                recover();
            else
                break;
            printf("\n 请继续输入命令 \n");
            scanf("%d",&command);
        }
        return 0;
    }

          2、可变分区分配并回收内存空间(首次适应法)

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #define getpch(type) (type*)malloc(sizeof(type))
    int SIZE;
    int id=0;
    struct sif //内存分区使用说明表
    {
        int id;
        int size;
        int begin_adress;
        char status;//F-已分配,T-未分配
        struct sif *next;
    }*p,*ready=NULL;
    
    typedef struct sif SIF;
    
    int allocate(int size)//分配内存
    {
        p=ready;
        while(p!=NULL)
        {
            if((p->status=='T')&&(p->size>=size))
            {
                p->status='F';
                if(((p->size)-size)>0)//若分配后存在碎片
                {
                    if((p->next->status)=='T')//若下一相邻存储块未被分配,将此碎片与相邻存储片合并
                    {
                        p->next->begin_adress=p->next->begin_adress-(p->size-size);
                        p->next->size=p->next->size+(p->size-size);
                        p->next=p->next->next;
                    }
                    else//若下一相邻存储块已被分配,为此碎片新建一存储块
                    {
                        SIF *q=getpch(SIF);
                        q->id=id++;
                        q->size=(p->size)-size;
                        q->status='T';
                        q->begin_adress=p->begin_adress+size;
                        q->next=p->next;
                        p->next=q;
                        p->size=size;
                    }
                }
                return 1;
            }
            p=p->next;
        }
        return 0;
    }
    void disp()//显示当前内存分配情况
    {
        printf("\n 当前内存分配情况如下:\n");
        printf("\n |id |size |begin_adress |status \n");
        p=ready;
        while(p!=NULL)
        {
            printf("\n %d| %d| %d| %c\n",p->id,p->size,p->begin_adress,p->status);
            p=p->next;
        }
    }
    void Input()
    {
        int d=0;
        SIF *last=ready;
        printf("\n 请输入现有内存的大小:  (起始地址从0开始) \n");
        scanf("%d",&SIZE);
        //初始化内存信息
        while(d!=SIZE)
        {
            p=getpch(SIF);
            p->id=id++;
            p->size=rand()%(63-1+1)+1;//使用随机函数分配存储块size
            p->begin_adress=d;
            if((id%2)==1)
                p->status='F';
            else
                p->status='T';
    
            p->next=NULL;
            if(d>(SIZE-(p->size)))
            {
                p->size=SIZE-d;
            }
            d+=p->size;
            if(ready==NULL)
            {
                ready=p;
                last=ready;
            }
            else
            {
                last->next=p;
                last=last->next;
            }
        }
        disp();//打印内存说明表
    }
    void allocation()//采用首次适应算法分配内存
    {
        int num1;
        int i,s;
        //给作业分配内存空间
        printf("\n 请输入待分配内存的作业个数:");
    
        scanf("%d",&num1);
        for(i=0; i<num1; i++)
        {
            printf("\n 请输入第%d个作业的大小: ",i);
            scanf("%d",&s);
            if(allocate(s)==1)
            {
                printf("\n 已为该作业分配内存空间\n");
                printf("\n 存储该作业内存空间的详细信息如下:\n");
                printf("\n 内存块号:%d, 内存大小:%d \n",p->id,p->size);
            }
            else
                printf("\n 未能该该作业分配内存 \n");
        }
        disp();
    }
    void recover()//作业完成后回收资源
    {
        int i,k,num;
        printf("\n 请输入需要释放的作业个数: ");
        scanf("%d",&num);
        for(i=0; i<num; i++)
        {
            printf("\n 请输入存储该作业的内存分区说明表的ID \n");
            scanf("%d",&k);
            p=ready;
            SIF *q=getpch(SIF);
    
            while(p!=NULL)
            {
                if(p->id==k)
                {
                    p->status='T';
    
                    if((q->status=='T')&&(p->next->status=='T'))//释放资源上下相邻块均未存储信息,合并三块为一块
                    {
                        (q->size)+=p->size+p->next->size;
                        (q->next)=p->next->next;
                    }
                    if((q->status=='T')&&(p->next->status=='F'))//相邻上块未分配,下层已分配,合并上层及当前块
                    {
                        (q->size)+=p->size;
                        (q->next)=p->next;
                    }
                    if((q->status=='F')&&(p->next->status=='T'))//相邻下块未分配,上层已分配,合并下层及当前块
                    {
                        p->size=(p->size)+(p->next->size);
                        p->next=p->next->next;
                    }
    
                    printf("\n 已释放该作业所占用的资源 \n");
                    break;
                }
                q=p;
                p=p->next;
            }
        }
        disp();
    }
    int main()
    {
        int command;
        Input();//初始化内存说明表
        printf("\n 请输入命令,给作业分配资源输入1,释放资源输入2,退出请输入任意键:\n");
        scanf("%d ",&command);
        while(1)
        {
            if(command==1)
                allocation();
            else if(command==2)
                recover();
            else
                break;
            printf("\n 请继续输入命令 \n");
            scanf("%d",&command);
        }
        return 0;
    }

         3、段页式存储管理分配内存空间并实现逻辑地址转换功能

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #define getpch(type) (type*)malloc(sizeof(type))
    
    int n;//全局变量,段表长度
    
    typedef struct page//页表
    {
        int id;
        int b_num;
        struct black *b;
    }pg;
    
    typedef struct paragraph//段表
    {
        int id;//段号
        int size;
        struct page *adress;//页内地址
    }ph;
    
    ph PH[10];
    pg PG[10][10];
    
    void disp()
    {
        printf("\n 当前段表分配情况如下:\n");
        printf("\n |id |pagesize |page_b_adress \n");
        int i;
        for(i=0; i<(int)(sqrt(n)); i++)
        {
            printf("\n %d\t%d\t%d \n",PH[i].id,PH[i].size,PH[i].adress);
        }
    
        printf("\n 当前页表分配情况如下:\n");
        int j;
        for(i=0; i<(int)(sqrt(n)); i++)
        {
            printf("\n  第%d段页内分配情况如下:\n",i);
            printf("\n |id  | b_num \n");
            for(j=0;j<(int)(sqrt(PH[i].size));j++)
            printf("\n %d\t%d \n",PG[i][j].id,PG[i][j].b_num);
        }
    }
    void Input()//输入函数
    {
        int i,d,m;
        printf("\n 初始化段表 \n");
        printf("\n 请输入段表的起始地址、段表的长度:");
        scanf("%d%d",&d,&n);
    
        m=d;
        for(i=0; i<(int)(sqrt(n)); i++)
        {
            PH[i].id=i;
            int j=rand()%4;
            PH[i].size=(int)(pow(2,j));//页表长度
            PH[i].adress=m;
            m+=PH[i].size;
            int k;
            for(k=0; k<j; k++)
            {
                PG[i][k].id=k;//每个页面2KB
                PG[i][k].b_num= rand()%(127-0+1)+1;
            }
        }
        disp();
    }
    int adress_mapping()//地址映射函数
    {
        int a,b,c,n1=0,d=0;
        printf("\n请依次输入作业的段号、段内页号及业内地址: ");
        scanf("%d%d%d",&a,&b,&c);
        if(a>n)//判断是否越界
        {
            printf("\n 您输入的段号已越界 \n");
            return -1;
        }
    
        //若未越界,则进入页表
        int j=sqrt(PH[a].size);
        if(b>j)
        {
            printf("\n 您输入的页号已越界 \n");
            return -1;
        }
    
        //若未越界,则返回物理地址
        return PG[a][b].b_num*256+c;
    
    }
    
    int main()
    {
        Input();
        int command;
        printf("\n 计算物理地址请按1,退出请按0 \n");
        scanf("%d",&command);
        while(command==1)
        {
            printf("\n %d \n",adress_mapping());
            printf("\n 计算物理地址请按1,退出请按0 \n");
            scanf("%d",&command);
        }
    }
    

    展开全文
  • 就像JVM虚拟机一样有自己的内存分配和回收,计算机的内存也有多种内存管理方案。计算机执行程序的大致过程,就是先从内存中读取指令,接着被CPU解码,然后根据需要从内存中读取操作数,执行完指令后可能写回内存。在...

    1. 内存管理

    计算机的作用就是执行程序,而程序是则指令和数据的集合,我们肯定需要把他存放在一个位置,即内存。就像JVM虚拟机一样有自己的内存分配和回收,计算机的内存也有多种内存管理方案。

    计算机执行程序的大致过程,就是先从内存中读取指令,接着被CPU解码,然后根据需要从内存中读取操作数,执行完指令后可能写回内存。在这个过程中从可以发现需要从内存中读取程序的指令和操作数,这个过程是怎么实现的呢?

    1.1 地址绑定

    以下为用户程序的大致执行过程

    97d4a3b8d5e1ba165418ccd30f754bad.png

    通常将指令和数据绑定到内存地址有以下几种情况:

    编译时:编译时就知道进程将在内存中的驻留地址,可以生成绝对代码。若发生变化,必须重新编译

    加载时:即地址绑定会延迟到加载时进行

    运行时:程序可以在运行时从一个内存段移到另一个内存段,且需要特定的硬件辅助完成,而绝大多数操作系统采用这种方式

    1.2 交换技术

    在分时系统中,用户的进程比内存能容纳的数量要多,这就需要在磁盘上保存那些内存放不下的进程。在需要运行这些进程时,再将它们装入内存。进程从内存移到磁盘并再移动回内存称为交换。交换技术是进程在内存与外存之间的动态调度,是由操作系统控制的。

    注意通常一个交换出的进程需要交换回它原来所占有的内存空间的。这一限制是由程序的地址绑定方式实现的。编译和加载是肯定不行的,运行是可以的!

    交换技术的缺点:

    由于交换时需要花费大量的CPU时间,这将影响对用户的响应时间,因此,减少交换的信息量是交换技术的关键问题。

    1.3 连续内存分配

    连续分配方式是指为一个用户程序分配一个连续的内存空间,连续分配方式有单一连续分配,固定分区分配和动态分区分配。

    单一连续分配

    内存在此方式下分为系统区和用户区,系统区仅供操作系统使用,通常在低地址部分;用户区是为用户提供的,除系统区以外的内存区域,*这种方式无须进行内存保护,因为内存中只存在一道用户程序,(在任何时间,用户区域中最多只有一个任务),不会因为访问越界而干扰其它程序。 *

    - 优点是没有外部碎片,分配方式简单,可以采用覆盖技术,不需要其它的技术支持。

    - 缺点是只能用于单用户,单任务的操作系统中,有内部碎片,内存的利用率低,灵活性低(要求程序的存储空间小于等于内存可用空间,否则不能使用覆盖技术),周转时间长(必须等内存中的作业执行完毕,下一个任务才能进入内存并执行)。

    固定分区分配

    固定分区分配是最简单的一种多道程序存储管理方式,它将用户内存空间分成若干大小固定的区域。每个分区只放入一道作业,当有空闲分区时,便可再从当前队列中选出一个作业进入。

    固定分区是可用于多道程序设计的最简单的分配存储,无外部碎片,但是存在内部碎片,而且也是较为严重,并且不能实现多个进程共享一个内存区,所以存储效率低,不被现在的操作系统所通用。但是在某些操作系统控制多个相同对象时发挥重要作用。

    动态分区分配

    动态分区分配又称可变分区分配,是一种动态划分内存的分区方法,它并不预先的分配好内存空间,而是在程序装入时,根据程序的大小为其分配正好合适的内存空间来满足程序的需要,因此,系统分区的大小和数目是可变的。

    在进程装入或换入内存时,若内存中有多个足够大的内存块时,则操作系统必须确定为该进程分配哪个内存块,即以下四点内存分配策略:

    首次适应算法(First fit)

    按空闲分区依地址递增次序链接,分配内存时按顺序查找,放入第一个匹配到的空闲分区,会造成内部碎片,有着较大的浪费

    最佳适应算法(Best fit)

    将空闲分区按内存大小递增的顺序链接起来,分配内存时按照顺序放入第一个匹配的空闲分区。

    最坏适应算法(Worst fit)

    将空闲分区按容量递减的顺序链接起来,分配内存时放入第一个匹配的空闲分区,即最大的分区,造成内部碎片

    8ec1cb7dab4acdf45d2babc23f099f10.png

    动态分区在开始分配是很好的,但随着为进程不断的分配和释放内存空间,会产生越来越多的内存碎片,内存的利用率随之降低,这些小的内存块被称之为外部碎片,这些外部碎片可以通过紧凑技术来解决,即操作系统通过不断地对进程进行移动和整,但是这种操作需要动态重定位寄存器的支持,且相对比较费时

    1.4 非连续内存分配

    本作品采用《CC 协议》,转载必须注明作者和本文链接

    展开全文
  • 文章目录内存保护覆盖(Overlay)碎片整理:分区对换(Swapping)固定分区分配动态分区分配伙伴系统(Buddy system) 内存保护 需要保护操作系统不受用户进程的影响,同时保护用户进程不受其他用户进程的影响。两种...
  • 早期的分类:单一连续分配 固定分区分配 动态分区分配 动态重定位分区分配 其他    1.单一连续分配  内存分为系统区(仅供给OS使用,通常放在内存的低址部分)和用户区(除系统区外的全部内存空间,提供给...
  • 在上一篇文章中,介绍了关于程序从编译然后链接形成装入模块,再通过程序的装入过程把它装入内存。将程序装入内存,是需要给程序分配内存空间的...连续分配方式可以进一步分为单一连续分配固定分配方式、动态分区...
  • 实验四-内存管理之固定分区分配 算法思想: 预先将内存空间划分成若干个空闲分区, 分配过程根据用户需求将某一个满足条件的分区直接分配 (不进行分割),作业完成后回收对应内存。 整个分配过程分区大小和个数...
  • 内存管理笔记六、非固定分区内存管理 引言:第五篇笔记,介绍了固定分区内存管理方式。本篇笔记将介绍非固定分区内存管理。 内存管理笔记六、非固定分区内存管理 一、非固定分区内存管理 1.1、...
  • 动态分区分配及可重定位分区分配

    千次阅读 2020-03-23 22:40:39
    动态分区分配及可重定位分区分配 分区大小不固定 分区分配的数据结构 二维表格(连续存储结构) 空闲分区表记录空闲分区的大小,位置和状态 已分配区表记录已占用分区的大小,位置和状态 双向循环链表(离散...
  • 对系统内存分区按照是否连续分配的...2.固定分区分配 会产生内部碎片 3.动态分配分配 会产生外部碎片 ①最佳适应算法(小) ②最坏适应算法(大) ③首次适应算法(从低到高地址) ④循环首次适应算法(每次都从上...
  • 固定分区管理 1、等区划分 缺乏灵活性,程序过大装不进去,程序过小又浪费空间 2、非等区划分 相对具有灵活性 内存分配:建立一个分区说明表,每一个表标注状态已经分配的不能被重新分配,一直到分配内存被释放...
  • 在上一篇文章中,介绍了关于程序从编译然后链接形成装入模块,再通过程序的装入过程把它装入内存。将程序装入内存,是需要给程序分配内存空间的...连续分配方式可以进一步分为单一连续分配固定分配方式、动态分区...
  • 可变分区内存动态分配模拟 可变分区是指在进程装入内存时,把可用的内存空间“切出”一个连续的区域分配给进程,以适应进程大小的需要。整个内存分区的大小和...空闲分区链在每个分区中设置用于控制分区分配的信...
  • 固定内存分区(c语言实现) 一:内存的作用 内存是计算机的重要组成部分,它主要配合CPU的告诉运转,提高计算机的运行速度。在计算机内部执行的都是一道道程序,而程序是存储在外存(硬盘)中的,但外存的读取速度...
  • 固定分区管理方式的主存分配回收模拟系统的设计 固定分区法就是把内存区固定地划分为若干个大小不等的区域。系统对内存的管理和控制通过数据结构----分区说明表进行,分区说明表各分区号、分区大小、起始地址和是否...
  • 连续分配方式进一步分为:单一连续分配、固定分区分配、动态分区分配以及动态重定位分区分配。 2、单一连续分配 最简单的一种存储管理方式,但只能用于单用户、单任务的操作系统中。 采用这种存储管理方式时,可把...
  • 固定分区 可变分区 内存利用率 低 提高 内碎片 存在 不存在 外碎片 不存在 存在 随便解决方案 无 紧缩技术 并发程序 固定 可变 分区内存 固定 可变 内存管理...
  • 下面先介绍一个概念:页:一个固定长度的数据块,存储在二级存储器中(如磁盘)。数据页可以临时复制入内存的页框中。段:一个变长的数据块,存储在二级存储中,整个段可以临时复制到内存的可用区域(分段),或者将...
  • 后面详细讨论固定分区分配和可变式分区分配,它们都是分区存储管理。 固定分区分配内存划分为若干个固定大小的连续分区,每个分区装入一个作业,分区可以同等大小,也可以差异不等。面对分区大小的差异,...
  • 目录单道程序的内存管理多道程序的内存管理后面详细讨论固定分区分配和可变式分区分配,它们都是分区存储管理。固定分区分配内存划分为若干个固定大小的连续分区,每个分区装入一个作业,分区可以同等大小,也...
  • .预备内容:阅读操作系统的内存管理章节内容,理解固定分区的思想,并体会固定分区分配主存的具体实施方法。 2.实践准备:掌握一种计算机高级语言的使用。
  • 内碎片:(固定分区中) 作业获得的空间大于所需空间时多出来的一小部分用户不需要的空闲区(一般太小而无法使用)。 外碎片:(动态分区中) 进程之间的零星的小空闲区(如图后来的8K空间) 分区管理...
  • 内存的连续分配方式

    2019-07-10 16:27:13
    连续分配方式:是指为一个用户程序分配一个连续的内存空间。 连续分配方式可以进一步分为单一连续分配、固定分区分配、动态分区分配和动态重定位分区分配。...固定分区分配是将内存用户空间划分为若干个大小...
  • 目录思维导图单一连续分配固定分区分配动态分区分配 思维导图 单一连续分配 固定分区分配 动态分区分配
  • 固定分区分配: 把内存用户区划分成若干固定大小的分区,每个分区只装入一道作业 划分方法: 1.分区大小相等 缺点:不灵活,分区太大或太小都不行 2.分区大小不相等 把用户区分成含有多个较小的分区,适量的中等分区...
  • 固定分区分配3. 动态分区分配4. 知识回顾四、动态分区分配算法1. 首次适应算法2. 最佳适应算法3. 最坏适应算法4. 邻近适应算法五、基本分页存储管理1. 页框2. 页面3. 分页存储4. 页表5. 页号、页内偏移量的计算6. ...
  • 内存分配方式

    2017-03-22 15:22:58
    内存的分配方式分类:单一内存连续分配、固定分区内存分配、动态分区分配、动态重定位分区分配,下面介绍这四种内存分配方式:
  • 实验三 固定分区存储管理 一实验目的 通过编写固定分区存储管理的模拟程序 加深对操作系统存储管 理功能中的固定分区管理方式主存分配表等相应知识的理解 二实验内容 1实现固定分区存储管理方式下存储空间的分配和...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 464
精华内容 185
关键字:

内存固定分区分配