IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> CSAPP实验五:动态内存分配(Malloc lab) -> 正文阅读

[数据结构与算法]CSAPP实验五:动态内存分配(Malloc lab)

? ? ? ?本系列文章为中国科学技术大学计算机专业学科基础课《计算机系统》布置的实验,上课所用教材和内容为黑书CSAPP,当时花费很大精力和弯路,现来总结下各个实验,本文章为第五个实验——动态内存分配(Malloc lab)。

一、实验名称:Malloc?lab

二、实验学时: 3

三、实验内容和目的:

? ? ?1. 目的

? ? ? ?/afs/cs/project/ics/im/labs/malloclab/

? ? ? ?在该实验中,需要用C语言实现一个动态存储分配器(dynamic storage allocater)。需要实现malloc、free、realloc等功能。当然不仅要正确的实现相关功能也要满足速度效率等要求。

? ? ?2. 步骤

tar xvf malloclab-handout.tar解压文件

我们需要修改的唯一文件是mm.c,包含如下几个需要实现的函数

int mm_init(void);

void *mm_malloc(size_t size);

void mm_free(void *ptr);

void *mm_realloc(void *ptr, size_t size)

? ? 3.?解释

mm_init:在调用mm_malloc,mm_realloc或mm_free之前,调用mm_init进行初始化,正确返回0。

mm_malloc:在堆区域分配指定大小的块,分配的空间,返回的指针应该是8字节对齐的

mm_free:释放指针指向的block

mm_realloc:返回指向一个大小为size的区域指针,满足一下条件:

if ptr is NULL, the call is equivalent to mm_malloc(size);

if size is equal to zero, the call is equivalent to mm_free(ptr);

if ptr is not NULL:先按照size指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来ptr所指内存区域

? ? 4. 可以调用的函数

void *mem_sbrk(int incr): Expands the heap by incr bytes, where incr is apositive non-zero integer and returns a generic pointer to the first byte of the newly allocated heap area. 
void *mem_heap_lo(void):Returns a generic pointer to the first byte in the heap. 
void *mem_heap_hi(void): Returns a generic pointer to the last byte in the heap. 
size_t mem_heapsize(void):Returns the current size of the heap in bytes. 
size_t mem_pagesize(void): Returns the system’s page size in bytes (4K onLinux systems). 

? ? 5. 验证方法

mdriver.c:负责测试mm.c的正确性,空间利用率和吞吐量
-f <tracefile>: ?-f后添加一些trace file来测试我们实现的函数
-V:打印出诊断信息
./mdriver -V ?-f short1-bal.rep

? ? 6. 编程规则

? ? 不能改变mm.c中函数接口

? ? 不能直接调用任何内存管理的库函数和系统函数malloc, calloc, free, realloc, sbrk, brk

? ? 不能定义任何全局或者静态复合数据结构如arrays, structs, trees,允许使用integers, floats, and pointers等简单数据类型

? ? 只要提交mm.c文件

? ?四、实验步骤及结果:?

? ?1. mm_init函数

? ? ?空闲块的组织方法-Segregated free list方法?
? ? ?segregated free list 中大小类的分类方法如下,并且将该list表放在heap的头部,通过序言块将它与数据隔离。在每一个大小类中,空闲块按照size由大到小排序。

*
* mm_init - initialize the malloc package.
* The return value should be -1 if there was a problem in performing the initialization, 0 otherwise
*/
int mm_init(void)
{
int listnumber;
char *heap; 

/* 初始化分离空闲链表 */
for (listnumber = 0; listnumber < LISTMAX; listnumber++)
{
segregated_free_lists[listnumber] = NULL;
}
/* 初始化堆 */
if ((long)(heap = mem_sbrk(4 * WSIZE)) == -1)
return -1;
/* 这里的结构参见本文上面的“堆的起始和结束结构” */
PUT(heap, 0);
PUT(heap + (1 * WSIZE), PACK(DSIZE, 1));
PUT(heap + (2 * WSIZE), PACK(DSIZE, 1));
PUT(heap + (3 * WSIZE), PACK(0, 1));
/* 扩展堆 */
if (extend_heap(INITCHUNKSIZE) == NULL)
return -1;
return 0;
}

? ? ? 空闲块查找方法 - best fit

? ? ? 因为同一大小类中空闲块由小到大排序,所以查找是第一个合适的就是最适配的mm_malloc函数。

? ? 2.mm_malloc函数

/*
* mm_malloc - Allocate a block by incrementing the brk pointer.
* Always allocate a block whose size is a multiple of the alignment.
*/
void *mm_malloc(size_t size)
{
if (size == 0)
return NULL;
/* 内存对齐 */
if (size <= DSIZE)
{
size = 2 * DSIZE;
}
else
{
size = ALIGN(size + DSIZE);
}

int listnumber = 0;
size_t searchsize = size;
void *ptr = NULL;
while (listnumber < LISTMAX)
{
/* 寻找对应链 */
if (((searchsize <= 1) && (segregated_free_lists[listnumber] != NULL)))
{
ptr = segregated_free_lists[listnumber];
/* 在该链寻找大小合适的free块 */
while ((ptr != NULL) && ((size > GET_SIZE(HDRP(ptr)))))
{
ptr = PRED(ptr);
}
/* 找到对应的free块 */
if (ptr != NULL)
break;
}
searchsize >>= 1;
listnumber++;
}
/* 没有找到合适的free块,扩展堆 */
if (ptr == NULL)
{
if ((ptr = extend_heap(MAX(size, CHUNKSIZE))) == NULL)
return NULL;
}
/* 在free块中allocate size大小的块 */
ptr = place(ptr, size);
return ptr;
}

? ? ?3. mm_free函数

/*
* mm_free - Freeing a block does nothing.
*/
void mm_free(void *ptr)
{
size_t size = GET_SIZE(HDRP(ptr));

PUT(HDRP(ptr), PACK(size, 0));
PUT(FTRP(ptr), PACK(size, 0));
/* 插入分离空闲链表 */
insert_node(ptr, size);
/* 注意合并 */
coalesce(ptr);
}

? ? 4.?mm_realloc函数

? ? ? ?mm_realloc 改进:

? ? ? ?对于请求的newsize>原始的oldsize这种情况,我们将运用类似coalesce中的方法,先去检查前后是否有空闲块,并是否满足前后空闲块和当前已分配的空闲块size相加大于newsize,如果是则合并,不需要再重新请求空闲块。如果不行,则需要重新mm_malloc一块新的空间。

/*
* mm_realloc - Implemented simply in terms of mm_malloc and mm_free
*/
void *mm_realloc(void *ptr, size_t size)
{
void *new_block = ptr;
int remainder;
if (size == 0)
return NULL;
/* 内存对齐 */
if (size <= DSIZE)
{
size = 2 * DSIZE;
}
else
{
size = ALIGN(size + DSIZE);
}
/* 如果size小于原来块的大小,直接返回原来的块 */
if ((remainder = GET_SIZE(HDRP(ptr)) - size) >= 0)
{
return ptr;
}
/* 否则先检查地址连续下一个块是否为free块或者该块是堆的结束块,因为我们要尽可能利用相邻的free块,以此减小“external fragmentation” */
else if (!GET_ALLOC(HDRP(NEXT_BLKP(ptr))) || !GET_SIZE(HDRP(NEXT_BLKP(ptr))))
{
/* 即使加上后面连续地址上的free块空间也不够,需要扩展块 */
if ((remainder = GET_SIZE(HDRP(ptr)) + GET_SIZE(HDRP(NEXT_BLKP(ptr))) - size) < 0)
{
if (extend_heap(MAX(-remainder, CHUNKSIZE)) == NULL)
return NULL;
remainder += MAX(-remainder, CHUNKSIZE);
}
/* 删除刚刚利用的free块并设置新块的头尾 */
delete_node(NEXT_BLKP(ptr));
PUT(HDRP(ptr), PACK(size + remainder, 1));
PUT(FTRP(ptr), PACK(size + remainder, 1));
}
/* 没有可以利用的连续free块,而且size大于原来的块,这时只能申请新的不连续的free块、复制原块内容、释放原块 */
else
{
new_block = mm_malloc(size);
memcpy(new_block, ptr, GET_SIZE(HDRP(ptr)));
mm_free(ptr);
}
return new_block;
}

? ? 5.实验结果?

?测试用例1:99分

测试用例2:93分

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-13 12:32:05  更:2021-08-13 12:34:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 20:54:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码