当试图释放堆管理器分配的内存时会发生啥,它分配的比要求的多?

Posted

技术标签:

【中文标题】当试图释放堆管理器分配的内存时会发生啥,它分配的比要求的多?【英文标题】:what happens when tried to free memory allocated by heap manager, which allocates more than asked for?当试图释放堆管理器分配的内存时会发生什么,它分配的比要求的多? 【发布时间】:2011-01-21 03:16:07 【问题描述】:

这个问题是在一次采访中问我的。

假设 char *p=malloc(n) 分配了 n 个以上的内存,比如说分配了 N 个字节的内存,并且 free(p) 用于释放分配给 p 的内存。

堆管理器可以执行这种错误的分配吗? 现在会发生什么,是释放 n 个字节还是释放 N 个字节?

有什么方法可以查出释放了多少内存?

编辑

有什么方法可以查出释放了多少内存?

聊胜于无,

mallinfo() 可以揭示“Fred Larson”所指出的一些亮点

【问题讨论】:

为什么你认为这样的分配是错误的?无论malloc() 分配了多少“实际”字节,您都只能使用n 字节,free() 将释放所有分配的字节。大多数malloc 实现会分配更多空间,然后出于效率原因请求。一个实现定义了mallocfree,根据定义,它们必须就分配方案达成一致。 【参考方案1】:

其他答案已经很好地解释了如何处理块大小。要了解释放了多少内存,我能想到的唯一解决方案是在释放前后调用mallinfo()

【讨论】:

【参考方案2】:

这是 malloc 的默认行为。它将返回NULL 或指向内存部分的指针,至少与您要求的一样长。因此,是的,免费必须能够处理比要求更长的时间来摆脱内存。

找出实际空闲或分配了多少内存是一个特定于平台的问题。

【讨论】:

【参考方案3】:

通常堆管理器会释放它分配的任何东西。它将这些信息存储在某处,并在调用 free() 时进行查找。

如果堆管理器分配的内存比请求的多,它就不是“故障”。堆管理器通常使用固定的块大小,并在满足请求时四舍五入到下一个适当的块大小。堆管理器的工作是尽可能提高效率,而大的效率往往源于一些小的低效率。

【讨论】:

“大的效率往往源于一些小的低效率”很好的引述 8^)【参考方案4】:

是的,几乎每次malloc() 都会发生这种情况。 malloc 块头包含有关块大小的信息,当调用 free() 时,它将该数量返回到堆中。不是故障,是正常运行。

例如,一个简单的实现可能只将块的大小存储在返回指针之前的空间中。然后,free() 看起来像这样:

void free(void *ptr)

    size_t *size = (size_t *)ptr - 1;

    return_to_heap(ptr, *size);

这里使用return_to_heap() 表示一个函数,该函数执行将指定的内存块返回到堆以供将来使用的实际工作。

【讨论】:

有没有办法查出释放了多少内存? @rozuur:malloc() 分配的所有内存将由free() 释放。我认为你真正的问题是如何找出分配了多少内存。 (答案呢?如果分配成功,至少按照要求的数量。) rozuur:看看这个页面:msdn.microsoft.com/en-us/library/ms220938(VS.80).aspx 它让你了解当你请求一块内存时实际做了什么。大多数实现与此非常相似。 @rozuur 重要的一点是,分配的实际大小并不重要。这些是实现细节,你不应该太担心它们,除非你怀疑它们会给你带来问题,而大多数时候它们不会。 @Rozur,为了后代! 1)所有分配的内存都将被释放(N,根据问题)。 2) 能不能查出到底分配了多少内存,取决于内存管理器有没有公布这个信息。 3)没有标准的函数来获取malloc()分配的字节数(虽然不同的厂商可能会选择提供这样的函数)。 4) 许多内存管理器将n 取整为二的下一个幂,从而确保您永远不会浪费超过一半的内存。【参考方案5】:

是的,堆管理器可以返回超过 n 个字节的块。使用free 释放返回的指针是完全安全的(也是必需的!),free 将释放所有指针。

许多堆实现通过将元数据块插入堆来跟踪它们的分配。 free 将查找该元数据以确定要释放多少内存。不过,这是特定于实现的,因此无法知道 malloc 给了您多少,通常您不必在意。

【讨论】:

以上是关于当试图释放堆管理器分配的内存时会发生啥,它分配的比要求的多?的主要内容,如果未能解决你的问题,请参考以下文章

C 内存的动态分配怎么用?有啥建议吗?内存分配中栈与堆到底有啥不同啊?

了解自己主动内存管理

linux采用啥方法实现内存的分配和释放

C#基础之内存分配

程序中内存从哪里来2之堆内存详解

智能指针的原理和实现