【问题标题】:What happens if I realloc to smaller size?如果我重新分配到更小的尺寸会发生什么?
【发布时间】: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标准库实现级别的答案。

【问题讨论】:

  • 非常在很大程度上取决于使用的分配器,也取决于在mallocrealloc 下使用的操作系统自己的分配器。而且,如果您从应用程序的角度学习动态分配,那么实际上没有必要了解任何这些低级实现特定的东西。因此,请扩展您的问题,告诉我们您在哪个级别进行研究,应用程序级别、C 标准库实现级别或操作系统级别。
  • “页眉”和“页脚”是 CRT 实现内部。就应用程序代码而言,它所看到和操纵的只是你所谓的“有效负载”。如果那是 16 个字节并且您重新分配到 8 个字节,那么这 8 个字节的内容保证与前 8 个字节匹配。页眉/页脚内部发生的事情无关紧要,除非您碰巧正在编写 CRT 堆管理代码。
  • 如果您将块从 24 个字节缩小到 16 个字节,最后 8 个字节会丢失。函数realloc() 无法知道您的预期用途。剩下的 16 个字节保留它们之前的任何值。
  • 你可以研究GNU libcfree software源代码。在Linux上,它在syscalls(2)之上实现了mallocrealloc

标签: c dynamic-memory-allocation realloc libc


【解决方案1】:

您保留缓冲区的第一个 size 字节。

我看到了一个realloc(),它只会将末端打掉并用缓冲区的末端构造一个新的空闲堆块。

我看到另一个realloc() 会将缓冲区移动到最后并关闭前面。

我看到另一个realloc() 总是会分配一个新的缓冲区并移动内存。

我敢肯定,会发生奇怪的事情。

有时realloc() 会得出结论,在结尾处删减几个字节是不值得的,实际上并没有做任何事情。

【讨论】:

  • 我实际上必须实现自己的 realloc 例程,所以你的意思是我可以决定在这种情况下做什么?
  • @이호영:是的。归结为只是从任何一方阅读规范。
猜你喜欢
  • 2012-06-23
  • 2017-05-07
  • 2014-12-21
  • 1970-01-01
  • 2011-02-02
  • 1970-01-01
  • 1970-01-01
  • 2019-09-30
  • 1970-01-01
相关资源
最近更新 更多