当试图释放堆管理器分配的内存时会发生啥,它分配的比要求的多?
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
实现会分配更多空间,然后出于效率原因请求。一个实现定义了malloc
和free
,根据定义,它们必须就分配方案达成一致。
【参考方案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
给了您多少,通常您不必在意。
【讨论】:
以上是关于当试图释放堆管理器分配的内存时会发生啥,它分配的比要求的多?的主要内容,如果未能解决你的问题,请参考以下文章