8

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

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

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

有什么方法可以找到释放了多少内存?

编辑

有什么方法可以找到释放了多少内存?

有总比没有好,

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

4

5 回答 5

8

是的,这就是几乎每次你做的时候都会发生的事情malloc()malloc块头包含有关块大小的信息,当被free()调用时,它将该数量返回给堆。这不是故障,这是预期的操作。

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

void free(void *ptr)
{
    size_t *size = (size_t *)ptr - 1;

    return_to_heap(ptr, *size);
}

此处return_to_heap()使用的 where 表示执行将指定的内存块返回到堆以供将来使用的实际工作的函数。

于 2010-02-25T17:59:33.307 回答
4

是的,堆管理器被允许返回一个多于n字节的块。使用 释放返回的指针是完全安全的(也是必需的!)freefree并将释放所有指针。

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

于 2010-02-25T17:59:31.403 回答
1

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

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

于 2010-02-25T18:00:02.337 回答
1

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

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

于 2010-02-25T18:00:18.953 回答
1

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

于 2010-02-25T18:17:33.860 回答