⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 caozuoxitong.txt

📁 内存的分配与回收的课程设计 挺好用的 呵呵
💻 TXT
字号:
4.内存的分配与释放
	在Linux下编写一个C程序,申请一段内存空间,并在终端上显示其起始地址,在用户要求下能释放该内存空间。
功能要求:
(1)用malloc函数分配;
(2)显示所分配的内存起始地址; 
(3)按q键用free函数释放内存。



#include <iostream>
using namespace std;
#define MAX_PROCESSES 10 /*假定模拟实验中,系统允许的最多进程为10个*/ 
#define MAX_FREE_MEMORY_DISTRICT 10 /*假定模拟实验中,系统允许的空闲区表最多为10个*/ 
#define MIN_SIZE 100 
#define TRUE  1
#define FALSE  0
struct 
{ 
    long address; /*某进程装入模块在内存中起始地址*/ 
    long length; /*进程装入模块长度,单位为字节*/ 
 int ProcessId;//进程ID
    int UsedFlag; /*分配标志,TRUE表示该表项已分配,FALSE表示该表项未分配*/ 
}used_table[MAX_PROCESSES]; /*已分配区表*/ 
struct 
{ 
    long address; /*内存空闲区块起始地址*/ 
    long length; /*内存空闲区块长度,单位为字节*/ 
    int AllocFlag; /*表示该表项是否指向空闲内存块,TRUE表示已指向某空闲区块,FALSE表示未指向某空闲区块*/ 
}free_table[MAX_FREE_MEMORY_DISTRICT]; /*空闲区表*/ 
void allocate(int ProcessId,long ProcessMemLength) //进程ID,进程所需内存长度
/*采用最优分配算法分配ProcessMemLength大小的空间*/ 
{ 
    int i,k; 
    long FirstAddress; 
    k=-1; 
    for(i=0;i<MAX_FREE_MEMORY_DISTRICT;i++) /*寻找空间大于ProcessMemLength的最小空闲区*/ 
 {
        if((free_table[i].AllocFlag == TRUE) && (free_table[i].length>=ProcessMemLength)) 
        {
            if((k==-1) || (free_table[i].length<free_table[k].length))
   {
                k=i; 
   }
        }
 }
    if(k==-1)/*未找到可用空闲区,返回*/ 
 { 
        printf("无可用空闲区\n"); 
        return; 
 } 
    //找到可用空闲区,开始分配:若空闲区大小与要求分配的空间差小于MIN_SIZE大小,则空闲区全部分配;
 //若空闲区大小与要求分配的空间差大于MIN_SIZE大小,则从空闲区划出一部分分配*/ 
    if((free_table[k].length - ProcessMemLength) <= MIN_SIZE) 
 { 
        free_table[k].AllocFlag = FALSE; //表示该空闲区块已分配给该进程
        //该表项又可指向其他空闲区块,但还没有指向其他空闲区块
     FirstAddress=free_table[k].address; 
        ProcessMemLength=free_table[k].length; 
 } 
    else 
 { 
        free_table[k].length=free_table[k].length - ProcessMemLength; 
        FirstAddress = free_table[k].address+free_table[k].length; 
 } 
    /*修改已分配区表*/ 
    i=0; 
    while((used_table[i].UsedFlag == TRUE) && (i < MAX_PROCESSES)) /*寻找空表目*/ 
 {
        i++; 
 }
    if(i>=MAX_PROCESSES) /*无表目填写已分分区*/ 
 { 
        printf("无表目填写已分分区,错误\n"); 
        /*修正空闲区表*/ 
        if(free_table[k].AllocFlag == FALSE) 
  {
            /*前面找到的是整个空闲分区*/ 
            free_table[k].AllocFlag = TRUE; 
  }
        else 
  {/*前面找到的是某个空闲分区的一部分*/ 
            free_table[k].length=free_table[k].length+ProcessMemLength; 
            return; 
  } 
 } 
    else 
 {/*修改已分配表*/ 
        used_table[i].address=FirstAddress; 
        used_table[i].length=ProcessMemLength; 
        used_table[i].UsedFlag=TRUE; 
     used_table[i].ProcessId = ProcessId;
 } 
    return; 
}/*主存分配函数结束*/ 
void reclaim(int ProcessId) 
/*回收作业名为J的作业所占主存空间*/ 
{ 
    int i,k,j,s,t; 
    long FirstAddress;//内存起始地址
 long length; //该进程所需内存长度
    /*寻找已分配表中对应登记项*/ 
    s=0; 
    while(((used_table[s].ProcessId != ProcessId) || (used_table[s].UsedFlag == FALSE))
   && (s<MAX_PROCESSES))
    {
  s++;
 }
    if(s>=MAX_PROCESSES)/*在已分配表中找不到进程号为ProcessId的进程*/ 
 { 
        printf("找不到该进程\n"); 
        return; 
 } 
    /*修改已分配表*/ 
    used_table[s].UsedFlag=FALSE; 
    /*取得归还分区的起始地址S和长度L*/ 
    FirstAddress=used_table[s].address; 
    length=used_table[s].length; 
    j=-1;k=-1;i=0; 
    /*寻找回收分区的空闲上下邻,上邻表目k,下邻表目j*/ 
    while((i < MAX_FREE_MEMORY_DISTRICT) && ((j == -1) || (k==-1)) )
 { 
        if(free_table[i].AllocFlag == TRUE) 
  { 
            if(free_table[i].address+free_table[i].length==FirstAddress)/*找到上邻*/ 
   {
    k=i;
   } 
            if(free_table[i].address==FirstAddress+length)/*找到下邻*/
   {
    j=i;
   } 
  } 
        i++; 
 } 
    if(k!=-1) /*上邻空闲区*/ 
 {
  if(j!=-1) 
  /* 上邻空闲区,下邻空闲区,三项合并*/ 
  { 
   free_table[k].length=free_table[j].length+free_table[k].length+length; 
   free_table[j].AllocFlag = FALSE; 
  } 
  else 
  {
   /*上邻空闲区,下邻非空闲区,与上邻合并*/ 
   free_table[k].length=free_table[k].length+length; 
  }
 }
    else  /*上邻非空闲区*/ 
 {
  if(j!=-1)/*上邻非空闲区,下邻为空闲区,与下邻合并*/ 
  { 
   free_table[j].address=FirstAddress; 
   free_table[j].length=free_table[j].length+length; 
  } 
  else 
  /*上下邻均为非空闲区,回收区域直接填入*/ 
  { 
   /*在空闲区表中寻找空栏目*/ 
   t=0; 
   while((free_table[t].AllocFlag == TRUE) && (t < MAX_FREE_MEMORY_DISTRICT))
   {
    t++; 
   } 
   if(t >= MAX_FREE_MEMORY_DISTRICT)/*空闲区表满,回收空间失败,将已分配表复原*/ 
   { 
    printf("主存空闲表没有空间,回收空间失败\n"); 
    used_table[s].UsedFlag = TRUE; 
    return; 
   } 
   free_table[t].address=FirstAddress; 
   free_table[t].length=length; 
   free_table[t].AllocFlag = TRUE; 
  } 
 }
    return; 
}/*主存回收函数结束*/ 
void main( ) 
{ 
    int i, SelectItem; 
    long ProcessMemLength; //进程所需内存长度
    int ProcessId; 
    /*空闲分区表初始化:*/ 
    free_table[0].address=1000; 
    free_table[0].length=10000; 
    free_table[0].AllocFlag = TRUE; 
    for(i=1;i<MAX_FREE_MEMORY_DISTRICT;i++) 
        free_table[i].AllocFlag =FALSE; 
    /*已分配表初始化:*/ 
    for(i=0;i<MAX_PROCESSES;i++) 
        used_table[i].UsedFlag=FALSE; 
    while(1) 
 { 
        cout<<"选择功能项(0-退出,1-分配主存,2-回收主存,3-显示主存)"<<endl; 
        cout<<"选择功项(0~3) :"; 
        cin>>SelectItem; 
        switch(SelectItem) 
  { 
            case 0: exit(0); /*a=0程序结束*/ 
            case 1: /*a=1分配主存空间*/ 
            cout<<"请输入进程ID号和进程所需内存长度Length: "; 
            //scanf("%*c%c%f",&J,&xk); 
   cin >>ProcessId>>ProcessMemLength;
            allocate(ProcessId,ProcessMemLength);/*分配主存空间*/ 
            break; 
            case 2: /*a=2回收主存空间*/ 
            cout<<"输入要回收分区的进程ID号"; 
            cin>>ProcessId; 
            reclaim(ProcessId);/*回收主存空间*/ 
            break; 
            case 3: /*a=3显示主存情况*/ 
            /*输出空闲区表和已分配表的内容*/ 
            cout<<"输出空闲内存区表:\n起始地址 长度"<<endl; 
            for(i=0;i<MAX_FREE_MEMORY_DISTRICT;i++) 
   {
    if(free_table[i].AllocFlag == TRUE)
    {
     cout<<free_table[i].address<<" \t"<<free_table[i].length<<endl; 
    }
   }
            cout<<"输出已分配内存进程表:\n进程ID 起始地址 长度 分配标志"<<endl; 
            for(i=0;i<MAX_PROCESSES;i++)
   {
                if(used_table[i].UsedFlag == TRUE)
    {
                    cout<<used_table[i].ProcessId<<" \t"<<used_table[i].address<<" \t";
     cout<<used_table[i].length<<" \t"<<used_table[i].UsedFlag<<endl; 
    }
   }
            break; 
           default:printf("没有该选项\n"); 
  }/*case*/ 
 }/*while*/ 
}/*主函数结束*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -