通过引用澄清 malloc() 是否在每个系统上分配连续内存

use*_*r47 1 c malloc dynamic-memory-allocation

在 K&R 书的第 8 章中,解释了malloc()如何在空闲内存中创建一个块列表,每个块都指向下一个块(粗略地说),并且不需要是连续的。另一方面,每个人都声称 malloc() 以连续的方式分配内存,我看到指针算术被大量使用,并且该网站上也有类似的问题。但是,始终没有任何官方消息来源

我阅读了 C 参考资料,发现没有提及有关连续性的内容,我发现最好的内容是在 Linux 和 Windows 手册页上,他们在系统上确保了此属性。

因此:malloc()是否仅在规范的现代系统上提供连续内存(例如,使指针算术合法),或者它是由 > C89 标准管辖的规则,而我天真地忽略了这一点?请提供官方参考。谢谢。

PS:这不仅仅是一个理论问题。我正在为旧的 DOS 系统编写一些代码,我需要确定malloc的正确用法。

编辑:我现在明白我的错误了,谢谢。也就是说,我仍然无法找到一个官方资源,其中明确指出单个malloc()调用返回连续内存(为什么此信息不简单地包含在标准库中的函数描述下方...... ?)例如,这里没有任何痕迹(https://en.cppreference.com/w/c/memory/malloc)。

Vla*_*cow 5

引用意味着如果您多次调用 malloc,则分配的块不必是相邻的。

但在每次调用 malloc 时,它都会分配相邻字节的单个内存范围。如果它不能做到这一点,它将返回一个空指针。

来自 C 标准(7.22.3 内存管理函数)

1 通过连续调用aligned_alloc、calloc、malloc 和realloc 函数分配的存储的顺序和连续性未指定。如果分配成功,则返回的指针会被适当对齐,以便可以将其分配给具有基本对齐要求的任何类型对象的指针,然后用于访问分配的空间中的此类对象或此类对象的数组(直到空间被显式释放)...


Zil*_*g80 5

我想我可以引用这本书的相关段落:

malloc 不会根据编译的固定大小数组进行分配,而是根据需要向操作系统请求空间。由于程序中的其他活动也可能在不调用此分配器的情况下请求空间,因此 malloc 管理的空间可能不是连续的。因此,它的空闲存储被保存为空闲块列表。每个块包含一个大小、一个指向下一个块的指针以及空间本身。块按存储地址递增的顺序保存,最后一个块(最高地址)指向第一个块。

您误解了它,它告诉您每次连续调用 malloc 不一定都是连续分配的空间。这并不意味着一个分配的块不是连续的。事实上,在当今的操作系统和现代 CPU 中,游戏中还有一个MMU,我建议您阅读相关内容。

  • 哦,是的,是的,现在我清楚地知道问题出在哪里了!我理解每个块只是内存的一个_单_字节,因此需要在它们之间跳转。相反,每个块_已经_由足够的连续单元组成来满足用户请求。然后,当重复 malloc 时,它会在另一个位置返回另一个块。因此,各个块是稀疏的,但每个块在内部都是连续的并且对应于单个调用。感谢您的帮助,我非常感激! (2认同)