实验四、主存空间的分配和回收
1. 目的和要求
1.1. 实验目的
用高级语言完成一个主存空间的分配和回收程序,以加深对动态分区分配方式及其算法的理解。
1.2. 实验要求
采用连续分配方式之动态分区分配存储管理,使用首次适应算法、循环首次适应算法、最佳适应算法和最坏适应算法4种算法完成设计。
(1)**设计一个作业申请队列以及作业完成后的释放顺序,实现主存的分配和回收。采用分区说明表进行。
(2)或在程序运行过程,由用户指定申请与释放。
(3)设计一个空闲区说明表,以保存某时刻主存空间占用情况。
把空闲区说明表的变化情况以及各作业的申请、释放情况显示。
2. 实验内容
根据指定的实验课题,完成设计、编码和调试工作,完成实验报告。
3. 实验环境
可以选用Visual C++作为开发环境。也可以选用Windows下的VB,CB或其他可视化环境,利用各种控件较为方便。自主选择实验环境。
4. 参考数据结构:
#include<stdio.h>
#include<conio.h>
#include<string.h>
#define MAX 24
struct partition{
char pn[10];
int begin;
int size;
int end; ////////
char status; //////////
};
typedef struct partition PART;
#include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE_MIN 2 #define MEMSIZE_MAX 1024 #define FALSE 0 #define TRUE !FALSE /*采用最佳分配法*/ typedef int BOOL; typedef struct _MEM_LINK { char cName; /*作业名*/ int iStartAddr; /*分区起始地址*/ int iMemSize; /*分区大小*/ BOOL iState; /*分区状态,1表示已分配, 0表示未分配*/ struct _MEM_LINK* next; } MEM_LINK, *PMEM_LINK; PMEM_LINK g_pslnkHead; /*初始化内存使用情况*/ void init() { g_pslnkHead=(PMEM_LINK)malloc(sizeof(MEM_LINK)); memset(g_pslnkHead, 0, sizeof(MEM_LINK)); g_pslnkHead->iMemSize = MEMSIZE_MAX; } int menu() { int i; printf("\n\n==========================================\n"); printf("\n\n1. 分配内存\n"); printf("2. 回收内存\n"); printf("3. 显示内存使用情况\n"); printf("4. 退出\n"); printf("\n==========================================\n"); printf("\n请输入选择:"); scanf("%d",&i); getchar(); return(i); } /*分配内存函数,c为作业名,usize是要分配的大小*/ int my_malloc(char c,int usize) { PMEM_LINK psNewMem = NULL, plnkTmp = NULL; BOOL bRepeatName = FALSE; int iTmp = g_pslnkHead->iMemSize - usize*SIZE_MIN; if (iTmp <= 0) /* 如果没有足够的空间分配 */ return FALSE; plnkTmp = g_pslnkHead; while (plnkTmp != NULL) { if (plnkTmp->cName == c) { bRepeatName = TRUE; break; } plnkTmp = plnkTmp->next; } if (bRepeatName) /* 如果作业名重复 */ { return FALSE; } /* 创建新的节点 */ psNewMem = (PMEM_LINK)malloc(sizeof(MEM_LINK)); /* 结构体设零 */ memset(psNewMem, 0, sizeof(MEM_LINK)); /* 设置节点内容 */ psNewMem->cName = c; psNewMem->iMemSize = usize*SIZE_MIN; psNewMem->iStartAddr= MEMSIZE_MAX - g_pslnkHead->iMemSize; psNewMem->iState = TRUE; plnkTmp = g_pslnkHead; /* 查找链表最尾节点 */ while (plnkTmp->next != NULL) plnkTmp = plnkTmp->next; /* 把新创建的节点加入到链表中 */ plnkTmp->next = psNewMem; /* 在整体内存中去掉以分配的部分 */ g_pslnkHead->iMemSize -= usize*SIZE_MIN; return TRUE; } /*回收内存函数,c是撤销的进程的作业名;*/ int my_free(char c) { PMEM_LINK plnkBK = g_pslnkHead, /* 保留上次搜索的节点 */ plnkTmp = g_pslnkHead->next; BOOL bFind = FALSE; int iFreeSize = 0; /* 搜索链表 */ while (plnkTmp != NULL) { if (plnkTmp->cName == c) { /* 如果找到节点,退出循环 */ bFind = TRUE; break; } plnkBK = plnkTmp; plnkTmp = plnkTmp->next; } if (bFind) { /* 把找到的节点从链表中摘除并释放 */ g_pslnkHead->iMemSize += plnkTmp->iMemSize; plnkBK->next = plnkTmp->next; /* 保留要释放内存的大小 */ iFreeSize = plnkTmp->iMemSize; /* 释放 */ free(plnkTmp); /* 把未释放内存的开始地址提前, 防止内存碎片 */ plnkTmp = plnkBK->next; while (plnkTmp != NULL) { plnkTmp->iStartAddr -= iFreeSize; plnkTmp = plnkTmp->next; } } return bFind; } void disp() { PMEM_LINK pTmp; int i = 0; pTmp = g_pslnkHead; printf("\n分区号 作业名 起始地址 分区大小 状态"); while(pTmp) { printf("\n%4d %c %4d %4d %4d", i, pTmp->cName, pTmp->iStartAddr, pTmp->iMemSize, pTmp->iState); pTmp = pTmp->next; i++; } } void main() { int i; char c; init(); i = menu(); while (i!=4) { if (i==1) { printf("\n作业名(一个字符):"); scanf("%c",&c); printf("作业占内存大小:"); scanf("%d", &i); if(my_malloc(c,i)) printf("\n分配成功!!!"); else printf("\n分配失败!!!"); } else if (i==2) { printf("\n输入要回收分区的作业名(一个字符):"); scanf("%c",&c); if(my_free) printf("\n回收成功!!!"); else printf("\n回收失败!!!"); } else if(i==3) disp(); i = menu(); } }