可能重复:
C 编程:free 如何知道要释放多少?
大家好,
当我们定义自由(指针)时,操作系统将如何知道我必须释放多少大小。我的意思是我们不提供任何 size ,只提供指向 free 语句的指针。内部如何处理大小?
谢谢,尼尔
可能重复:
C 编程:free 如何知道要释放多少?
大家好,
当我们定义自由(指针)时,操作系统将如何知道我必须释放多少大小。我的意思是我们不提供任何 size ,只提供指向 free 语句的指针。内部如何处理大小?
谢谢,尼尔
操作系统不会有任何线索,因为 free 不是系统调用。但是,当内存最初由 malloc() 分配时,您的 C 库内存分配系统会以某种方式记录大小,因此它知道要释放多少。
大小存储在分配器内部,传递给 free 的指针用于访问该数据。一个非常基本的方法是在指针之前存储 4 个字节的大小,所以从指针中减去 4 会给你一个指向它大小的指针。
请注意,操作系统不会直接处理这个问题,它是由您的 C/C++ 运行时分配器实现的。
当你调用 malloc 时,C 库会自动在堆上为你腾出一个空间。因为在堆上创建的东西是动态创建的,所以在任何给定时间点堆上的东西都不知道,因为它是堆栈的。因此,库将跟踪您在堆上分配的所有内存。
在某些时候,您的堆可能如下所示:
p---+
V
---------------------------------------
... | used (4) | used (10) | used (8) | ...
---------------------------------------
该库将跟踪为每个块分配了多少内存。在这种情况下,指针 p 指向中间块的开始。
如果我们执行以下调用:
free(p);
然后图书馆会在堆上为你释放这个空间,就像这样......
p---+
V
----------------------------------------
... | used (4) | unused(10) | used (8) | ...
----------------------------------------
现在,下次您正在寻找一些空间时,请使用以下电话:
void* ptr = malloc(10);
新未使用的空间可能会再次分配给您的程序,这将使我们能够减少程序使用的总内存量。
ptr---+
V
----------------------------------------
... | used (4) | used(10) | used (8) | ...
----------------------------------------
您的图书馆可能在内部处理大小管理的方式是不同的。实现这一点的一种简单方法是在分配的每个块的开头添加额外的字节数(例如,我们会说 1)以保存每个块的大小。所以我们之前的堆内存块看起来像这样:
bytes: 1 4 1 10 1 8
--------------------------------
... |4| used |10| used |8| used | ...
--------------------------------
^
+---ptr
现在,如果我们说块大小将被四舍五入以被 2 整除,我们在大小的末尾有一个额外的位(因为我们总是可以假设它为 0,我们可以方便地使用它来检查是否相应的块被使用或未使用。
当我们在 free 中传递一个指针时:
free(ptr);
库会将给定的指针移回一个字节,并将已使用/未使用的位更改为未使用。在这种特定情况下,我们甚至不必真正知道块的大小来释放它。只有当我们尝试重新分配相同数量的数据时,它才会成为一个问题。然后,malloc 调用将继续下去,检查下一个块是否空闲。如果它是空闲的,那么如果它是正确大小的块将返回给用户,否则将在堆的末尾切割一个新块,并在必要时从操作系统分配更多空间。