- 姓名:吕煜华
- 学号:201821121046
- 班级:计算1812
1. 记录内存空间使用情况
定义一个结构体AB来记录pid,大小,起始地址,进程名,定义一个指针allocated_block_head来指向链表的头结点
/*每个进程分配到的内存块描述*/ typedef struct allocated_block{ int pid; int size; int start_addr; char process_name[NAME_LEN]; struct allocated_block *next; }AB; /*进程分配内存块链表的首指针*/ AB *allocated_block_head = NULL;
2. 记录空闲分区
定义空闲分区的结构体free_block_type,定义一个指针free block指向链表表头
/*描述每一个空闲块的数据结构*/ typedef struct free_block_type{ int size; int start_addr; struct free_block_type *next; }FBT; /*指向内存中空闲块链表的首指针*/ FBT *free_block;
3. 内存分配算法
为适应这种算法要使得空闲区的大小按起始地址升序排列。根据首次适配算法在空闲分区链表中搜索合适空闲分区进行分配,分配时如果找到可满足空闲分区且分配后剩余空间足够大,则分割;如果找不可满足需要的空闲分区但空闲分区之和能满足需要,则进行空闲分区的合并,然后再分配。在成功分配内存后,应保持空闲分区按照首次适配算法有序。
int allocate_mem(AB *ab){ FBT *fbt,*pre; int request_size=ab->size; fbt = pre = free_block; int f = find_free_mem(request_size); if(f == -1){ //不够分配 printf("空闲内存不足,内存分配失败! "); return -1; }else{ if(f == 0){ memory_compact(); } //执行分配 do_allocate_mem(ab); } //重新排布空闲分区 rearrange(ma_algorithm); return 1; } //执行分配内存 void do_allocate_mem(AB *ab){ int request = ab->size; FBT *tmp = free_block; while(tmp != NULL){ if(tmp->size >= request){ //分配 ab->start_addr = tmp->start_addr; int shengyu = tmp->size - request; tmp->size = shengyu; tmp->start_addr = tmp->start_addr + request; return ; } tmp = tmp->next; } } /*首次适应算法,空闲区大小按起始地址升序排序*/ void rearrange_FF(){ if(free_block == NULL || free_block->next == NULL) return; FBT *t1,*t2,*head; head = free_block; for(t1 = head->next;t1;t1 = t1->next){ for(t2 = head;t2 != t1;t2=t2->next){ if(t2->start_addr > t2->next->start_addr){ int tmp = t2->start_addr; t2->start_addr = t2->next->start_addr; t2->next->start_addr = tmp; tmp = t2->size; t2->size = t2->next->size; t2->next->size = tmp; } } } }
4. 内存释放算法
内存释放:找到对应的链表节点,释放释放杀死进程的内存块,归还进程的已分配的存储空间,按大小从小到大排序,释放链表节点。
//释放链表节点 int dispose(AB *free_ab){ AB *pre,*ab; if(free_ab == allocated_block_head){ //如果要是释放第一个节点 allocated_block_head = allocated_block_head->next; free(free_ab); return 1; } pre = allocated_block_head; ab = allocated_block_head->next; while(ab!=free_ab){ pre = ab; ab = ab->next; } pre->next = ab->next; free(ab); return 2; } //更新分区表 int free_mem(AB *ab){ int algorithm = ma_algorithm; FBT *fbt,*pre,*work; fbt = (FBT*)malloc(sizeof(FBT)); if(!fbt) return -1; fbt->size = ab->size; fbt->start_addr = ab->start_addr; //插至末尾 work = free_block; if(work == NULL){ free_block = fbt; fbt->next == NULL; }else{ while(work ->next != NULL){ work = work->next; } fbt->next = work->next; work->next = fbt; } //按地址重新排布 rearrange_FF(); pre = free_block; while(pre->next){ work = pre->next; if(pre->start_addr + pre->size == work->start_addr ){ pre->size = pre->size + work->size; pre->next = work->next; free(work); continue; }else{ pre = pre->next; } } //按照当前算法排序 rearrange(ma_algorithm); return 1; } int kill_process(int pid){ AB *ab; ab = find_process(pid); if(ab!=NULL){ free_mem(ab); dispose(ab); return 0; }else{ return -1; } }
5. 运行结果
(1)产生测试数据
(2)解释结果:
初始化的空闲分区的内存范围为0到1024,
第一次操作为进程process-01分配了从0开始,大小为51的一块内存单元,分配后空闲分区内存剩余地址从51开始,大小为973的一块区域。
第二次操作为进程process-02分配了从51开始,大小为54的一块内存单元,分配后空闲分区内存剩余地址从105开始,大小为919的一块区域。
第三次操作为进程process-03分配了从105开始大小为11的一块内存单元,分配后空闲分区内存剩余地址从116开始,大小为908的一块区域。