【发布时间】:2021-03-17 13:14:40
【问题描述】:
我目前正在研究动态内存分配,我有一个关于 realloc 函数的问题。 我了解到新分配的块的内容应该与旧块的内容相同,直到新旧大小的最小值,其他一切都未初始化。
如果堆块正在使用边界标记,而我正在重新分配到更小的大小怎么办?
我要问的是,例如,这是一个 24 字节大小的内存块,它的前 4 个字节是标题,中间的 16 个字节是有效负载,最后 4 个字节是页脚。我已经把这个块缩小到 16 个字节,它的前 4 个字节将是新块的标题,最后 4 个字节将是新块的页脚。
首先,标题会改变吗?标头应包含有关块大小和分配位的信息,但新块的内容应相同。这是否意味着标题中的所有内容(包括块大小信息)都保持不变,这对我来说似乎完全没用?
其次,我应该如何放置新块的页脚?页脚应该出现在新块的第 13 ~ 16 个字节。但是新旧块的内容应该相同,最多16个字节,如果我把页脚放在第13~16个字节就违反了!
很抱歉提出这么冗长的问题,但我现在非常困惑。 希望我能找到答案。
关于问题的其他信息)
我目前正在 CS:APP 的 malloc 实验室工作,该实验室希望我通过编写自己的 malloc、free 和 realloc 例程版本来设计分配器。它说这些函数应该与相应的 libc malloc、free 和 realloc 例程的语义相匹配。
现在我实际上正在实现自己的 realloc 函数,我对这些情况感到困惑。所以希望能得到C标准库实现级别的答案。
【问题讨论】:
-
这非常在很大程度上取决于使用的分配器,也取决于在
malloc和realloc下使用的操作系统自己的分配器。而且,如果您从应用程序的角度学习动态分配,那么实际上没有必要了解任何这些低级实现特定的东西。因此,请扩展您的问题,告诉我们您在哪个级别进行研究,应用程序级别、C 标准库实现级别或操作系统级别。 -
“页眉”和“页脚”是 CRT 实现内部。就应用程序代码而言,它所看到和操纵的只是你所谓的“有效负载”。如果那是 16 个字节并且您重新分配到 8 个字节,那么这 8 个字节的内容保证与前 8 个字节匹配。页眉/页脚内部发生的事情无关紧要,除非您碰巧正在编写 CRT 堆管理代码。
-
如果您将块从 24 个字节缩小到 16 个字节,最后 8 个字节会丢失。函数
realloc()无法知道您的预期用途。剩下的 16 个字节保留它们之前的任何值。 -
你可以研究GNU libc的free software源代码。在Linux上,它在syscalls(2)之上实现了
malloc和realloc
标签: c dynamic-memory-allocation realloc libc