GCC 不熟悉内存分配的行为

GCC Unfamiliar behavior with memory allocation

提问人:MatanCode 提问时间:7/16/2023 更新时间:7/16/2023 访问量:64

问:

我看到,每当我连续分配两次,一个接一个, 我假设 gcc 分配的第二个内存足够远 - 因此,如果我使用 realloc 进行第一个分配,它不必立即更改其在内存中的位置。

此外,我注意到在第二次分配之前正好 8 个字节,有字符 '!'。

我认为它的存在是为了通知 gcc 第一次分配是否会覆盖第二次分配;

事实上,每次我手动覆盖它时(如图所示),内存地址中的某些内容都会发生变化,但“!”在第二次分配之前仍保留 8 个字节,看起来 GCC 在内存分配之间提供了另一个额外的内存空间。

我的问题是,这是否是一种熟悉的行为? 如果是这样,是否有参考?

在图片中,

  1. 首次打印:使用第一个 val1。
  2. 第二次打印:使用第二个 val1。
  3. 第三次打印:使用第三次 Val1。(覆盖“!”,因此第二个分配跳到前面)。
  4. 第四版印刷品:我增加了循环中的条件限制,所以 我们可以看到第二次分配,正如你所看到的,“!” 仍然存在,在第二次分配之前 8 个字节。

enter image description here

c GCC malloc 分配

评论

1赞 Some programmer dude 7/16/2023
请不要发布文字图片。将文本作为文本复制粘贴到您的问题中。
1赞 Some programmer dude 7/16/2023
另一方面,打印 (,cast is needed) 指针的正确格式说明符是 。请改用它。即使在 64 位系统上,系统和编译器仍然使用 32 位。printfvoid *%plong
1赞 Some programmer dude 7/16/2023
至于可能的问题(只能猜测,因为不可能看到完整的代码!),不要超出数组和分配内存的界限。越界会导致未定义的行为
1赞 Weather Vane 7/16/2023
请注意,应该是printf("%ld\n", (long)str1);printf("%p\n", (void*)str1);

答:

4赞 chqrlie 7/16/2023 #1

您的所有观察结果都来自具有未定义行为的代码,这些代码试图在 返回的已分配块之前和/或之后探索内存。malloc()

您观察到的字节可能包含内存分配器的辅助数据,用于跟踪分配的块,并在释放块或重新分配块时执行适当的簿记。

与其从观察中猜测,不如尝试阅读实现并了解其工作原理。GNU libc 是开源的,Apple Libc 和 FreeBSD libc 也是开源的。查找和其他分配函数的源代码并阅读文档。内存分配包有据可查。malloc()

有几种相互竞争的方法来处理内存分配,试图在控制内存碎片的同时优化性能,这是一个经典的问题,50 多年来一直在努力提出最佳折衷方案。