CSAPP  && lab5

实验指导书:

http://download.csdn.net/detail/u011368821/7951657

实验材料:

http://download.csdn.net/detail/u011368821/8019293

搞定这个实验还是要看一下曾经的笔记,再复习一下block的组织方式。仅仅看link里面第11节,动态内存分配的部分就能够了

http://blog.csdn.net/cinmyheart/article/details/38136375

然后看看对block的探測性学习

http://blog.csdn.net/cinmyheart/article/details/38174421

The only file you will modify and turn in is mm.c.

Your dynamic storage allocator will consist of the following three functions (and several helper functions), which are declared in mm.h and defined in mm.c:

int mm_init(void);
void* mm_malloc(size_t size);
void mm_free(void* ptr);

Your job is to complete this implementation by filling out mm_malloc() and mm_free().

任务就是利用下面现有的API去补全mm_malloc()和mm_free()

Provided Code

We define a BlockInfo struct designed to be used as a node in a doubly­linked explicit free list, and the following functions for manipulating free lists:

BlockInfo* searchFreeList(int reqSize): returns a block of at least the requested size if one exists (and NULL otherwise).
void insertFreeBlock(BlockInfo* blockInfo): inserts the given block in the free list in LIFO manner.
void removeFreeBlock(BlockInfo* blockInfo): removes the given block from the free list.

In addition, we implement mm_init and provide two helper functions implementing important parts of the allocator:

void requestMoreSpace(int incr): enlarges the heap by incr bytes (if enough memory is available on the machine to do so).
void coalesceFreeBlock(BlockInfo* oldBlock): coalesces any other free blocks adjacent in memory to oldBlock into a
single new large block and updates the free list accordingly.

这里free list的实现介绍: 这里须要说明一下的就是header处于低地址,footer处于高地址. 这里说明的原因是由于实现的时候会有指针的加减,注意一下就是了 :-)

sizeAndTags中记录的size信息是整个block的大小。包含了struct BlockInfo结构体的大小

论证: 观察struct BlockInfo结构体在内存中的分布

正是依据内存布局的特点,这里blockCursor仅仅想当前block头的时候减去一个WORD_SIZE会得到什么?

前一个block的footer 即boundary tag,由此获知当前block的前一个block的大小

My answer:

/* Allocate a block of size size and return a pointer to it. */
void* mm_malloc (size_t size) {
size_t reqSize;
BlockInfo * ptrFreeBlock = NULL;
BlockInfo * ptrNextBlock = NULL;
size_t blockSize;
size_t precedingBlockUseTag;
size_t* ptrNextBlockFooter = NULL; // Zero-size requests get NULL.
if (size == 0) {
return NULL;
} // Add one word for the initial size header.
// Note that we don't need to boundary tag when the block is used!
size += WORD_SIZE;
if (size <= MIN_BLOCK_SIZE) {
// Make sure we allocate enough space for a blockInfo in case we
// free this block (when we free this block, we'll need to use the
// next pointer, the prev pointer, and the boundary tag).
reqSize = MIN_BLOCK_SIZE;
} else {
// Round up for correct alignment
reqSize = ALIGNMENT * ((size + ALIGNMENT - 1) / ALIGNMENT);
} // Implement mm_malloc. You can change or remove any of the above
// code. It is included as a suggestion of where to start.
// You will want to replace this return statement... ptrFreeBlock = searchFreeList(reqSize); if(!ptrFreeBlock)
{
requestMoreSpace(reqSize);
ptrFreeBlock = searchFreeList(reqSize);
} blockSize = SIZE(ptrFreeBlock->sizeAndTags); if(blockSize < reqSize + MIN_BLOCK_SIZE)
{
reqSize = blockSize;
} precedingBlockUseTag = ptrFreeBlock->sizeAndTags & TAG_PRECEDING_USED;
ptrFreeBlock->sizeAndTags = reqSize | precedingBlockUseTag | TAG_USED; ptrNextBlock = (BlockInfo*)UNSCALED_POINTER_ADD(ptrFreeBlock,reqSize); if(reqSize != blockSize)
{
ptrNextBlock->sizeAndTags = (blockSize - reqSize) | TAG_PRECEDING_USED; ptrNextBlockFooter = (size_t *)UNSCALED_POINTER_ADD(ptrFreeBlock,blockSize - WORD_SIZE); (*ptrNextBlockFooter) = ptrNextBlock->sizeAndTags; insertFreeBlock(ptrNextBlock);
}
else
{
ptrNextBlock->sizeAndTags = ptrNextBlock->sizeAndTags | TAG_PRECEDING_USED; ptrNextBlockFooter = (size_t*)UNSCALED_POINTER_ADD(ptrNextBlock,SIZE(ptrNextBlock->sizeAndTags) - WORD_SIZE); (*ptrNextBlockFooter) = ptrNextBlock->sizeAndTags;
}
removeFreeBlock(ptrFreeBlock); return (void*)UNSCALED_POINTER_ADD(ptrFreeBlock,WORD_SIZE);
} /* Free the block referenced by ptr. */
void mm_free (void *ptr) {
size_t payloadSize;
size_t blockSize;
BlockInfo * blockInfo;
BlockInfo * followingBlock; // Implement mm_free. You can change or remove the declaraions
// above. They are included as minor hints. BlockInfo* prev_block = NULL;
BlockInfo* next_block = NULL; blockInfo = (BlockInfo*)UNSCALED_POINTER_SUB(ptr,WORD_SIZE);
followingBlock = (BlockInfo *)UNSCALED_POINTER_ADD(blockInfo,blockInfo->sizeAndTags); blockSize = SIZE(blockInfo->sizeAndTags);
payloadSize = blockSize - WORD_SIZE;
blockInfo->sizeAndTags = blockInfo->sizeAndTags & ~TAG_USED;
*(size_t *)UNSCALED_POINTER_ADD(blockInfo,payloadSize) = blockInfo->sizeAndTags;
followingBlock->sizeAndTags = followingBlock->sizeAndTags & ~TAG_PRECEDING_USED; if(followingBlock->sizeAndTags & TAG_USED == 0)
{
*(size_t *)UNSCALED_POINTER_ADD(followingBlock,SIZE(followingBlock->sizeAndTags) - WORD_SIZE) = followingBlock->sizeAndTags;
} insertFreeBlock(blockInfo);
coalesceFreeBlock(blockInfo); }

最后执行./mdriver

会有一下输出

题外话,追究这个malloc实现的话....事实上它就是基于已经有的stdlib.h已经有的malloc而实现的,介绍的是实现原理,利用双向链表

后面的额外练习表示没有耐心了,对于realloc...

到此,CSAPP的lab临时告一段落,以后还会峰峰补补的去更新 :-)

假设对这六个lab感兴趣,欢迎邮箱联系交流讨论

jasonleaster@gmail.com

版权声明:本文博客原创文章,博客,未经同意,不得转载。

CSAPP 六个重要的实验 lab5的更多相关文章

  1. 第六周课程总结&实验报告(四)

    实验报告(四) 一.实验目的 1.掌握类的继承 2.变量的继承和覆盖,方法的继承,重载和覆盖的实现 二.实验的内容 1.根据下面的要求实现圆类Circle. 圆类Circle的成员变量:radius表 ...

  2. 【iCore3 双核心板】例程二十六:MODBUS TCP实验——电源监控

    实验指导书及代码包下载: http://pan.baidu.com/s/1pKhxKd9 iCore3 购买链接: https://item.taobao.com/item.htm?id=524229 ...

  3. 第六章:Reminders实验:第二部分[Learn Android Studio 汉化教程]

    Learn Android Studio 汉化教程 Reminders Lab: Part 2 This chapter covers capturing user input through the ...

  4. 第六周课程总结&实验报告

    一.实验目的 (1)掌握类的继承 (2)变量的继承和覆盖,方法的继承,重载和覆盖的实现: 二.实验的内容 (1)根据下面的要求实现圆类Circle. 1.圆类Circle的成员变量:radius表示圆 ...

  5. 第六周学习总结&实验报告四

    一.实验目的 (1)掌握类的继承 (2)变量的继承和覆盖,方法的继承,重载和覆盖的实现: 二.实验的内容 (1)根据下面的要求实现圆类Circle. 1.圆类Circle的成员变量:radius表示圆 ...

  6. 【CSAPP】Shell Lab 实验笔记

    shlab这节是要求写个支持任务(job)功能的简易shell,主要考察了linux信号机制的相关内容.难度上如果熟读了<CSAPP>的"异常控制流"一章,应该是可以不 ...

  7. 20145330第六周《Java学习笔记》

    20145330第六周<Java学习笔记> . 这周算是很忙碌的一周.因为第六周陆续很多实验都开始进行,开始要准备和预习的科目日渐增多,对Java分配的时间不知不觉就减少了,然而第十和十一 ...

  8. CSAPP LAB: Buffer Overflow

    这是CSAPP官网上的著名实验,通过注入汇编代码实现堆栈溢出攻击.实验材料可到我的github仓库 https://github.com/Cheukyin/CSAPP-LAB/ 选择buffer-ov ...

  9. ORACLE 实验二

    实验二:数据操纵 实验学时:4学时 实验类型:综合型 实验要求:必修 一.实验目的 1.掌握SQL数据查询语句: 2.掌握SQL聚集函数的使用. 3.掌握SQL插入.改动.删除语句的使用. 二.实验内 ...

随机推荐

  1. UVALive 5790 Ball Stacking 解题报告

    比赛总结 题目 题意: 有n层堆成金字塔状的球,若你要选一个球,你必须把它上面那两个球取了,当然也可以一个不取.求选的球最大的权值和. 题解: 将这堆球转成举行,第一行是(0,0),第二个是(1,0) ...

  2. hadoop集群空间使用情况报告脚本

    近期集群空间有点紧张,总是操心空间不足而崩溃,近期扩容又不太现实,经与集群用户沟通发现:集群上存储了非常多没用的历史数据,能够删除,这样就能够通过一个crontab脚本每天生成集群空间使用报告,当使用 ...

  3. exit()和_exit()和return

    exit()和return的差别: 依照ANSI C,在最初调用的main()中使用return和exit()的效果同样. 但要注意这里所说的是"最初调用".假设main()在一个 ...

  4. debian下使用siege进行压力测试

    一:siege siege是开源的一个测试工具,可以对指定文本的URL列表进行负载测试,也可以在执行其他请求前让某个请求休眠,从而让你感觉某个用户在转移到web应用的下一个文档前正在读取该文档. ht ...

  5. linux kickstart 自动安装

    最近很多业务系统都是linux lnmp平台安装,反复的安装让人觉得很苦恼,仔细钻研了下kickstart .这里环境是red hat linux 5.8 32位,系统盘中的软件包里包含有kickst ...

  6. android &quot;Missing type parameter&quot; 错误

    近期在做android应该的时候出现这个问题,分析了一下日志,发现是在gosn解析的时候会出现,并且出现的时候非常诡异.于是去网上找相关资料. 发现这个问题还是比較常见的,原来是公布版本号和非正式公布 ...

  7. WPF中不规则窗体与WebBrowser控件的兼容问题解决办法

    原文:WPF中不规则窗体与WebBrowser控件的兼容问题解决办法 引言 这几天受委托开发一个网络电视项目,要求初步先使用内嵌网页形式实现视频播放和选单,以后再考虑将网页中的所有功能整合进桌面程序. ...

  8. 学习OpenCV第0天

    自2011年接触OpenCV已经有几年了,一直停留在写一些小程序,利用手冊完毕一些任务,一直没有深入研究当中代码,现在毕业,但各种原因未能进入图像处理行业,故现重学OpenCV,包含分析代码,学习算法 ...

  9. Visual Studio跨平台开发实战(5) - Xamarin Android多页面应用程式开发

    原文 Visual Studio跨平台开发实战(5) - Xamarin Android多页面应用程式开发 前言 大部份的Andr​​oid 都具有实体或虚拟的Back键. 因此在处理多页面应用程式时 ...

  10. Python3.2官方文件翻译--课堂笔记和异常是阶级

    6.7备注 有时喜欢Pasca在"录"和C中"数据体"的数据类型很实用.集合一些数据项. 一个空类定义能够清楚地显示: class Employee: pass ...