C++ 当尝试释放堆管理器分配的内存时,会发生什么情况?堆管理器分配的内存比要求的多?
这个问题是在一次采访中问我的 假设char*p=malloc(n)分配的内存超过n个字节,例如分配了n个字节的内存,空闲(p)用于释放分配给p的内存 堆管理器可以执行这种错误的分配吗? 现在会发生什么,是释放n个字节还是释放n个字节 有什么方法可以确定释放了多少内存 编辑 有什么方法可以确定释放了多少内存 总比没有好C++ 当尝试释放堆管理器分配的内存时,会发生什么情况?堆管理器分配的内存比要求的多?,c++,c,free,malloc,heap,C++,C,Free,Malloc,Heap,这个问题是在一次采访中问我的 假设char*p=malloc(n)分配的内存超过n个字节,例如分配了n个字节的内存,空闲(p)用于释放分配给p的内存 堆管理器可以执行这种错误的分配吗? 现在会发生什么,是释放n个字节还是释放n个字节 有什么方法可以确定释放了多少内存 编辑 有什么方法可以确定释放了多少内存 总比没有好 mallinfo()可以提供一些信息,正如“Fred Larson”指出的那样。是的,允许堆管理器返回超过n字节的块。使用free释放返回的指针是完全安全的(并且是必需的!),并且
mallinfo()可以提供一些信息,正如“Fred Larson”指出的那样。是的,允许堆管理器返回超过n字节的块。使用
free
释放返回的指针是完全安全的(并且是必需的!),并且free
将取消分配所有指针
许多堆实现通过向堆中插入元数据块来跟踪它们的分配
free
将查找该元数据以确定要释放的内存量。但是,这是特定于实现的,因此无法知道malloc
为您提供了多少,通常情况下,您不应该在意。是的,几乎每次使用malloc()
时都会发生这种情况。malloc
block头包含有关块大小的信息,当调用free()
时,它将该金额返回堆。这不是故障,这是预期的操作
例如,一个简单的实现可能只将块的大小存储在返回指针前面的空间中。然后,free()
void free(void *ptr)
{
size_t *size = (size_t *)ptr - 1;
return_to_heap(ptr, *size);
}
其中return\u to\u heap()
在这里用于表示将指定内存块返回堆供将来使用的实际工作的函数。通常,堆管理器将释放其分配的任何内存。它将此信息存储在某个位置,并在调用free()
时查找它
如果堆管理器分配的内存多于请求的内存,则它不是“错误的”。堆管理器通常使用固定的块大小,并且在满足请求时将舍入到下一个适当的块大小。堆管理器的任务是尽可能地提高效率,而高效率往往是由一些小的低效率造成的。这是malloc的默认行为。它将返回NULL
或指向内存部分的指针,其长度至少与您请求的长度相同。因此,是的,free必须能够处理比要求更长时间的内存清除
找出实际可用或分配了多少内存是一个特定于平台的问题 其他答案很好地解释了如何处理块大小。要了解释放了多少内存,我能想到的唯一解决方案是在释放前后调用mallinfo()
。为什么您认为这样的分配是错误的?无论分配了多少“实际”字节malloc()
,您只能使用n
字节,并且free()
将释放所有分配的字节。大多数malloc
实现都会分配更多的空间,而不是出于效率原因而请求的空间。一个实现定义了malloc
和free
,根据定义,他们必须就分配方案达成一致。是否有一种方法来确定释放了多少内存?@rozuur:malloc()
分配的所有内存都将被free()
释放。我认为你真正的问题是如何找出分配了多少内存。(答案呢?如果分配成功的话,至少和请求的一样多。)rozuur:看看这一页:它给出了当你请求一块内存时实际做了什么的想法。大多数实现都与此非常相似。@rozuur重要的一点是,分配的实际大小无关紧要。这些都是实现细节,您不应该太担心它们,除非您怀疑它们会给您带来问题,而大多数情况下它们不会。@Rozur,为了子孙后代!1) 将释放所有内存分配(N
,根据问题)。2) 您能否准确地知道分配了多少内存取决于内存管理器是否发布此信息。3) 没有标准函数可以获取malloc()
分配的字节数(尽管不同的供应商可能会选择提供这样的函数)。4) 许多内存管理器将n
归纳为下一个二次方,从而确保您不会浪费超过一半的内存。“通常,高效率源于一些小的低效率”尼斯引用8^)