【问题标题】:malloc and heap: extra memory for storing the size and linked list information?malloc 和堆:用于存储大小和链表信息的额外内存?
【发布时间】:2015-09-10 23:04:52
【问题描述】:

我有一个关于heapmalloc 的简单问题:

当我们使用malloc分配一些内存空间时:

int *p;
p = (int*) malloc (10*sizeof(int));

它实际上在堆中分配了 10 个字。但是,我的问题是:

实际使用的内存空间真的是10个字吗?

还是需要其他额外的空间来存储内存大小的值?

或者,甚至,因为堆被构造为链表,是否还有其他内存空间用于存储指向堆中列表的下一个节点的地址?

【问题讨论】:

  • 是的,malloc 有开销。这完全是特定于实现的。但总的来说,如果您的程序使用较少的大分配而不是许多小分配,那么它的内存效率会更高。
  • 它是实现定义的。但是,在任何情况下,管理分配的内存都会有一些开销。您可以从以下地址开始阅读:en.wikipedia.org/?title=Memory_management
  • 虽然问题基本相同,但那里的答案比这里的阐述要少。

标签: c++ c memory malloc heap-memory


【解决方案1】:

它完全依赖于实现。

a) 它可能在每个分配的节点之前有几个字节,其中包含节点的大小、指向下一个节点的指针,可能还有前一个节点指针和节点的类型。

b) 返回的项目可能除了其他分配外没有其他任何东西。其他地方的结构会跟踪分配的内容和空闲的内容,可能通过位图或微型并行列表。

c) 另一种变体提供了几个固定大小的块数组。一个数组可以提供 32 字节的块;另一个 128 字节块等。每个数组的位图管理分配。

d) 我见过的最小实现完全忽略了free()(即free() 是一个无操作)并在每个malloc() 分配池的下一块。


到目前为止,最常用的现代技术是a。变体 b 用于许多文件系统,如 NTFS 和 FAT。选项 c 在许多 DEC 操作系统中是/被青睐的,特别是对于内核使用。选项 d 被一些极简嵌入式环境使用,但有适当的警告。

在大多数实现中,请求的分配被四舍五入为算法方便的某个自然倍数(通常为 2、8、16 等)。因此,5、3、8、7、4、1 和 15 的一系列分配可能都被视为一个 16 字节的请求。

【讨论】:

  • 值得注意的是,还有许多其他技巧可能会花费额外的空间,例如使用特殊位模式填充以检测越界写入或有关分配的信息(代码的哪一部分进行了分配) 用于调试目的。
  • 也许可以添加一些关于optimistic allocation 的内容。 (顺便说一句:一个很好的答案!)
  • @chux:手册页提到乐观分配很有趣,但我不明白它是如何适用的。我认为这意味着sbrk() 很乐观,可能会导致malloc() 乐观,对吧?
  • OP 说“实际使用的内存空间真的是 10 个字?”思考malloc() 和其他人真正使用 内存的想法也是如此,因为真正可能发生的只是内存被标记为使用,但尚未使用,并且当真正使用发生时,“额外内存”可能会改变。 See here。如果那没有帮助,请不要打扰您的好答案。注意:乐观分配是一个独立于sbrk()的想法。
【解决方案2】:

内存分配取决于编译器库和操作系统。

两种语言都没有说明可以分配的最大内存量。您所保证的只是要求的尺寸。

因此,如果分配了任何额外的内存,它将取决于平台。

此外,分配更大空间时开销可能会更少。

尝试编写自己的内存分配器,看看需要什么,尤其是在释放内存时。

【讨论】:

    【解决方案3】:

    是的,malloc 的实现可以实际分配比您请求的内存多一点的内存,在分配内存的开头存储分配内存的大小,然后给您一个指向立即数的指针下一个内存地址。当您对该指针调用free 时,分配器将返回一点,读取缓冲区的大小,并计算出它实际需要释放多少。

    当然,另一种可能的实现可以保留一个列表、一个字典,或者在底层做一些完全不同的事情,只要它给你相同的指定行为。

    【讨论】:

      【解决方案4】:

      当您使用malloc 分配内存时,您得到的只是指向该内存中第一个地址的指针,并保证已分配了这么多字节供您使用。 如何分配和跟踪内存的详细信息取决于平台,您无法从程序中访问该信息。因此,虽然可能会为开销目的分配额外的内存,但您不能以跨平台的方式使用这些知识。

      【讨论】:

      • 当然。我正在简化情况,因为考虑 malloc 失败的情况并不真正适用于这个问题。
      猜你喜欢
      • 2019-10-10
      • 1970-01-01
      • 2021-03-02
      • 1970-01-01
      • 2017-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-23
      相关资源
      最近更新 更多