2010-02-25 73 views
8

这个问题在接受采访时被问到了我。当试图释放由堆管理器分配的内存时,会发生什么情况?

假设char * p = malloc(n)赋值多于n,例如分配N个字节的内存并释放分配给p的内存空间(p)。

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

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

编辑

有没有找到多少内存被释放的方法?

聊胜于无,

mallinfo()可以提供一些线索通过“弗雷德·拉森”为指出

+6

你为什么认为这样的分配有问题?无论分配多少“实际”字节“malloc()”,只能使用“n”个字节,而“free()”将释放所有分配的字节。大多数'malloc'实现分配更多的空间,然后出于效率原因请求。一个实现定义了“malloc”和“free”,根据定义,它们必须就分配方案达成一致。 – 2010-02-25 17:59:47

回答

8

是的,几乎每次你都会发生这种情况malloc()malloc块标题包含有关块大小的信息,当调用free()时,它将该量返回给堆。这不是错误的,它是预期的操作。

一个简单的实现可能会在返回的指针之前的空间中存储块的大小。然后,free()会是这个样子:

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

    return_to_heap(ptr, *size); 
} 

return_to_heap()用在这里的意思是,做指定的存储块返回堆供将来使用的实际工作的功能。

+0

有没有一种方法来找出有多少内存被释放? – Rozuur 2010-02-25 18:07:56

+0

@rozuur:所有由'malloc()'分配的内存都将被'free()'释放。我认为你真正的问题是如何找出分配了多少内存。 (和答案?至少与要求一样多,如果分配成功。) – Bill 2010-02-25 18:33:46

+1

rozuur:看看这个网页:http://msdn.microsoft.com/en-us/library/ms220938(VS.80) .aspx 它提供了一个想法,当你要求一大块内存时,实际做了什么。大多数实现与此非常相似。 – ThePosey 2010-02-25 18:40:58

4

是,堆管理器被允许返回超过ň字节的块。使用free释放返回的指针是完全安全的(并且是必需的!),并且free将释放所有的指针。

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

1

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

如果堆管理器分配的内存比请求的多,则它不是“错误”的。堆管理器通常使用固定的块大小,并在满足请求时将四舍五入到下一个适当的块大小。堆管理者的工作要尽可能高效,而且往往效率很高,只会造成一些小的低效率。

+0

“效率往往很高,因为效率很低”很好的报价8 ^) – caseman 2010-02-25 19:10:53

1

这是malloc的默认行为。它会返回NULL或指向内存部分的指针,至少与您要求的一样长。所以,自由必须能够处理比所要求的更长的时间。

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

1

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

相关问题