理解和实现 malloc

one*_*day 1 c malloc realloc

malloc 是如何在内部实现的?如何在以下必要条件下实现 malloc

• Malloc 至少分配请求的字节数

• malloc 返回的指针指向一个已分配的空间(即程序可以成功读写的空间;)

• 对 malloc 的其他调用不会分配此空间或其任何部分,除非该指针之前已被释放。

• malloc 应该易于处理:malloc 必须尽快终止(它不应该是 NP-hard !;)

• Malloc 还应提供调整大小和释放功能。

该函数遵循以下签名: Void * malloc(size_t size);

one*_*day 6

解决方案:为了编写一个malloc,我们需要知道堆从哪里开始和break位置,当然我们还需要能够移动break。我们将使用 sbrk() 系统调用来实现这一点。

在此处输入图片说明

Sbrk (n) 按给定的增量 n(以字节为单位)移动中断。

sbrk 的特殊情况:当 increment 为 null(即 sbrk(0))时,返回值是实际的中断地址(前一个和新的中断地址相同。)因此 sbrk 用于检索堆的开头,其中是中断的初始位置

Step -1 实施(不满足所有标准) 在此处输入图片说明

但是在高级目标得到满足时,它会根据请求的大小移动断点,用户将在堆上获得内存分配,而不满足重新分配并允许它释放的标准 1) 所以我们需要知道每个部分的开始位置和时间位于下一个的每个部分地址的开头。2) 该部分的大小是多少 3) 该部分是否免费 在此处输入图片说明

所以基本上我们需要一个包含以下内容的列表 在此处输入图片说明

免费使用 int 似乎是一个坏主意,但由于 struct 默认对齐,因此无关紧要。

我们必须注意的另一个条件是 malloc 必须返回对齐的地址。如上所示,元部分已经对齐,我们只需要确保数据部分也是如此。 在此处输入图片说明

查找块 Base 是指向堆起始点的全局指针 在此处输入图片说明

扩展堆——很简单,我们只是移动断点。 在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

现在我们可以执行我们的 malloc 函数,它只是所有经过的小块的包装器 在此处输入图片说明