免费如何知道自由有多少?

在C编程中,您可以将任何类型的指针作为参数传递给free,它如何知道分配的内存空间的大小? 每当我传递一个指向某个函数的指针,我还必须传递大小(即10个元素的数组需要接收10作为参数来知道数组的大小),但我不必将大小传递给免费功能。 为什么不,我可以在我自己的函数中使用这种相同的技术,以免我需要在数组长度的额外变量上使用购物车?


当你调用malloc() ,你指定了要分配的内存量。 实际使用的内存数量稍多于此,并且包含记录(至少)该块有多大的额外信息。 您不能(可靠地)访问其他信息 - 也不应:-)。

当你打电话给free() ,它只是查看额外的信息来找出块的大小。


C内存分配函数的大多数实现将存储每个块的记帐信息,可以是内嵌的,也可以是分开的。

一种典型的方式(内联)是实际分配一个头部和你要求的内存,填充到最小尺寸。 例如,如果您询问了20个字节,系统可能会分配一个48字节的块:

  • 包含大小,特殊标记,校验和,指向下一个/上一个块的指针等的16字节标题。
  • 32个字节的数据区(您的20个字节填充为16的倍数)。
  • 然后提供给您的地址是数据区的地址。 然后,当您释放该区块时, free会简单地输入您提供的地址,假设您没有填充该地址或周围的内存,请在它之前立即检查会计信息。 从图形上看,这将符合以下几点:

     ____ The allocated block ____
    /                             
    +--------+--------------------+
    | Header | Your data area ... |
    +--------+--------------------+
              ^
              |
              +-- The address you are given
    

    请记住,头部和填充的大小完全是实现定义的(实际上,整个事情是实现定义的(a),但内联会计选项是常见的)。

    会计信息中存在的校验和和特殊标记通常是错误的原因,例如,如果您覆盖它们或释放它们两次,则会出现“内存舞台损坏”或“双倍空闲”等错误。

    填充(使分配效率更高)是为什么有时您可以在不会造成问题的情况下稍微写出一点点,而不会造成问题(仍然,不要这样做,这是未定义的行为,并且仅仅因为它有时起作用,这意味着可以做到这一点)。


    (a)我已经在嵌入式系统中编写了malloc实现,无论您询问什么内容(即系统中最大结构的大小),您都获得了128字节,假设您要求128字节或更少(请求更多会遇到一个NULL返回值)。 一个非常简单的位掩码(即非内联)被用来决定是否分配一个128字节的块。

    我开发的其他人有16个字节的块,64个字节的块,256个字节的块和1K块的不同池,同样使用一个位掩码来决定使用或可用的块。

    这两个选项都设法减少了会计信息的开销,并增加了mallocfree的速度(在释放时无需合并相邻块),这在我们所处的环境中尤为重要。


    comp.lang.c常见问题清单:免费如何知道有多少个字节可用?

    malloc / free实现会记住每个块在分配时的大小,因此在释放时没有必要提醒它的大小。 (通常,大小存储在分配的块的旁边,这就是为什么如果分配的块的边界甚至稍微超出范围时通常会破坏)

    链接地址: http://www.djcxy.com/p/79193.html

    上一篇: How does free know how much to free?

    下一篇: Objective C: Memory Allocation on stack vs. heap