C语言中的free()函数问题

3

可能是重复的问题:
C编程:free如何知道要释放多少内存?

您好,

当我有以下代码时:

void *ptr = malloc(100); // alloc 100 bytes
// do sth
free(ptr);

free()函数如何知道需要释放多少空间?

谢谢!

--

好的,我已经找到其他类似的问题,请关闭 - 抱歉。


我认为这种问题在SO上已经被问了很多次了。所以也许应该有一个常见问题解答? - Nyan
2个回答

5
通常,这些信息包含在由malloc实现管理的某个内存区域中。这些信息通常在malloc向您分配实际内存之前出现,但这是一个实现细节,您不能依赖于此处任何内容。

1
实际上并没有malloc的实现。您的操作系统提供了实现。 - Luca Matteis
1
@Luca Matteis:不,通常不会。它是运行时库的一部分(在Unix上是libc,在Windows上是crt等)。例如,请参见Doug Lea的malloc实现(http://g.oswego.edu/dl/html/malloc.html),当然还有http://en.wikipedia.org/wiki/Malloc(甚至提到了Doug Lea的实现,所以我希望我没有离轨太远... :-) - Dirk
1
@Luca Matteis:这不是真的。malloc绝对是CRT函数。操作系统通常不关心堆管理这样微小的事情。它按照内存页(又称虚拟内存)为应用程序分配内存。而这块内存反过来在应用程序中被划分为分区。 - valdo
@Dirk,好的。我会让社区决定什么是操作系统的一部分,什么不是。当然有malloc的实现,但它们都与操作系统的工作方式紧密相关,因为那里是计算应该分配多少空间的所有逻辑发生的地方。由于问题的精神是要认识和理解free()如何知道要释放多少空间,所以不可避免地需要将操作系统带入主题,而不仅仅是malloc的实现。 - Luca Matteis
@JemeryP:当然需要。它通过sbrkmmapint 21hVirtualAllocEx或任何系统调用来分配原始内核,这是系统操作系统提供/要求的。请注意,处理对齐不一定仅仅是性能问题,而在许多系统上也是确保正确功能所必需的。 - Dirk
显示剩余2条评论

2

这是实现依赖性的,但通常底层系统有一个地址到块的映射表,并且它从该内存映射中知道大小。

下面是来自glibc的简化代码,它基本上展示了我刚才所说的。

void fREe(Void_t* mem)
{
  arena *ar_ptr;
  mchunkptr p;
  if (__free_hook != NULL) {
    (*__free_hook)(mem, NULL);
  }

  if (mem == 0)                              /* free(0) has no effect */
    return;

  p = mem2chunk(mem);

  if (chunk_is_mmapped(p))                       /* release mmapped memory. */
  {
    munmap_chunk(p);
    return;
  }

  ar_ptr = arena_for_ptr(p);
  chunk_free(ar_ptr, p);
  (void)mutex_unlock(&ar_ptr->mutex);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接