【问题标题】:Is the memory allocation done by malloc always contiguous?malloc 完成的内存分配是否总是连续的?
【发布时间】:2021-03-22 02:28:16
【问题描述】:

我在 K&R 书中读到“malloc 管理的空间可能不连续。每个块包含大小,指向下一个块的指针。”。但是当我使用 google 时,我看到大多数人都在说 malloc 总是进行连续的内存分配。所以请清除这个疑问。事实是什么? malloc 管理的空间始终是连续的,也可能是连续的,也可能不是连续的。

【问题讨论】:

  • 在内部,malloc 管理的内存不必是连续的。但是,返回给用户的任何内存都是连续的。
  • 这些陈述不存在争议。一是关于malloc() 管理的空间。另一个是关于malloc()分配的空间。

标签: c malloc kernighan-and-ritchie


【解决方案1】:

malloccallocrealloc 返回的单个内存块将始终是连续的。

由单独的 alloc 调用返回的下一个内存块可以位于任何地址,并且不需要与第一个块连续。

【讨论】:

    【解决方案2】:

    查看您阅读该句子的页面上的图表:

    带点的区域不属于 malloc,并且位于 malloc 管理的两个区域之间。不属于 malloc 的区域很可能由程序的另一部分分配(例如,使用 mmap(2))。它也可能只是没有分配。

    尽管在 malloc 管理的内存区域中存在这个“漏洞”,但 malloc(以及它的函数系列)仅分配连续的内存块。

    因此,malloc 管理的区域可能是不连续的,但 malloc 分配的块是连续的。

    【讨论】:

      【解决方案3】:

      您从一次调用malloc() 收到的内存段始终是连续的。对从不同呼叫返回的段没有任何保证。您可能会在第一次调用 malloc 时在程序开始时获得这种印象,但是随着内存以free() 返回到堆,返回的内存被重用,最后您以或多或少的分散量结束,对返回完全不相关的指针。

      另一方面,malloc() 使用sbrk(2) 系统调用来增加/减少数据段的大小,如果可能的话。但是在它不能使用sbrk()的情况下,malloc()使用memmap()来获得一个或多个堆来操作。 Memmap() 在写那本书时在 unix 系统中不可用,因此从那时起,原则上情况可能发生了很大变化。这些堆(mmap()ed)被映射到进程的虚拟空间,基于内核的许多可能情况,而不是malloc(),例如动态共享对象的加载,这与执行连续性相冲突地址空间。这些地址可能会显示不连续的内存范围,其中散布着其他完全不同的东西,例如物理内存附件(如果操作系统提供此服务,则为视频内存)内存映射文件、共享库等。

      另一方面,malloc 必须为它提供给您的每个内存块分配一些数据......许多实现将此块定位在给定段的一侧,因此即使这些块是连续的,您通常也不能使用它们之间的内存,否则您将破坏malloc() 用于处理堆的内存。

      【讨论】:

        猜你喜欢
        • 2010-10-12
        • 2019-06-10
        • 1970-01-01
        • 2023-04-08
        • 2011-01-15
        • 1970-01-01
        • 1970-01-01
        • 2010-10-05
        相关资源
        最近更新 更多