如何在内部实施malloc?如何在必要条件下实现malloc
•Malloc至少分配请求的字节数
•malloc返回的指针指向已分配的空间(即程序可以成功读取或写入的空间;)
•没有其他对malloc的调用会分配这个空间或它的任何部分,除非之前已经释放了指针。
•malloc应该易于处理:malloc必须尽快终止(它不应该是NP难的!;)
•Malloc还应提供调整大小和释放。
该功能符合以下签名: Void * malloc(size_t size);
答案 0 :(得分:1)
解决方案: 为了编写malloc代码,我们需要知道堆的开始位置和中断位置, 当然,我们需要能够休息一下。我们将使用sbrk()sys调用来实现这一点。
Sbrk(n)将中断移动给定的增量n(以字节为单位)。
sbrk的特例:当increment为null(即sbrk(0))时,返回的值是实际的中断地址(前一个和新的中断地址是相同的。)sbrk因此用于检索sbrk的开头作为休息的初始位置的堆
但是在高级别目标是满意的,它会按请求的大小移动断点,用户将在堆上获得内存分配,而不满足重新分配的标准并允许它自由 1)因此,我们需要知道每个部分的开始位置以及我们何时处于下一个部分的每个部分地址的开头。 2)该部分的大小是多少 3)如果该部分是免费的
免费使用int可能看起来不错,但由于struct默认情况下是对齐的,所以不重要。
我们必须注意的另一个条件是malloc必须返回对齐的地址。如上所述,meta部分已经对齐,我们只需要确保数据部分也是如此。
答案 1 :(得分:1)
来自 brk()的manual(2) 。
brk()和 sbrk()更改程序中断的位置,该位置定义了流程数据段的结尾(即,程序中断是未初始化数据段结束后的第一个位置)。增加程序中断会为进程分配内存;减少休息时间会释放记忆。
brk()将数据段的结尾设置为addr指定的值,当该值合理时,系统有足够的内存,并且进程不超过其最大数据大小(见 setrlimit(2))。
sbrk()按递增字节递增程序的数据空间。调用 增量为0的 sbrk()可用于查找当前位置 程序休息。
我会用它,因为老实说,我无法更好地定义这些功能。请注意,system calls提供的 brk()和 sbrk()均为Linux Kernel。这是它们与 malloc()系列之间的第一个主要区别 - malloc()和兄弟是GLibC实现。
这个SO Question会告诉你他们到底做了什么以及程序中断了什么,所以我不会在这里复制所有内容。
如上所述,它们由GLibC实现,并通过列表管理系统上的内存块。 简单地说(让我强调简单部分), malloc()会在该列表中找到符合请求大小的空闲块用户并返回该块的地址并将其标记为正在使用中;另一方面, free()会将该块返回到列表中。
您可以从here下载来源。截至目前,最新的是 2.22 。下载后,提取并转到 glibc-2.22 / malloc 。在此目录下,您将找到malloc(malloc.c)的源代码。
从 malloc.c 文件的第一个评论部分中提取:
算法的主要属性是:
对于大型(> = 512字节)请求,它是一个纯粹的最佳匹配器, 关系通常通过FIFO决定(即最近最少使用)。
对于小(默认情况下为<= 64字节)请求,它是一个缓存 分配器,用于维护快速回收块的池。
在两者之间,对于大型和小型请求的组合,它确实如此 它最好能够同时实现这两个目标。
对于非常大的请求(默认情况下> = 128KB),它依赖于系统 内存映射工具,如果支持。
有关更长但稍微过时的高级描述,请参阅 this.
我建议关注最后一个链接并阅读它。
此外,这个 PDF file解释了 malloc()和 free()的内部运作。
答案 2 :(得分:0)
我已经经历了多个SO答案,我相信下面的教程提供深入和一步一步实现所有四个功能..