我最近一直在尝试学习如何使用C
编程语言进行编程。
我目前无法理解C中free()
如何释放内存。
释放或释放记忆是什么意思?
例如,如果我有以下指针:
int *p = malloc(sizeof(int));
当我使用free(p)
解除分配时,它会做什么?它是否以某种方式将其标记为“ deallocated ”,因此应用程序可能会将其用于新分配?
它是否仅释放指针地址,或者指向的地址也被解除分配?
我会自己做一些实验来更好地理解这一点,但我是这个主题的新手,我甚至不知道如何调试C程序(我没有使用任何IDE)。
另外,如果int *p
实际上是指向int
数组的指针,该怎么办?
如果我调用free(p)
,它是否会释放整个数组或仅指向它所指向的元素?
我非常渴望最终理解这一点,我非常感谢任何帮助!
答案 0 :(得分:2)
释放或释放记忆是什么意思?
这意味着您已完成内存并准备将其返回内存分配器。
当我使用free(p)解除分配时,它会做什么?
具体是依赖于实现的,但对于典型的分配器,它将块放回到空闲列表中。分配器维护可供使用的块列表。当你要求一块内存时(通过调用malloc()
或类似内容),分配器在空闲块列表中找到一个适当的块,将其删除(因此它不再可用),并为你提供一个指向块的指针。当您调用free()
时,该过程将被反转 - 该块将被放回到空闲列表中,从而可以再次分配。
重要的是,一旦在指针上调用free()
,就不能再取消引用该指针。与内存相关的错误的常见原因是在释放指针后使用指针。出于这个原因,有些人认为在释放它之后立即设置指针nil
是一种有用的做法。类似地,你应该避免在你最初没有从分配器获得的指针上调用free()
(例如,不要释放指向局部变量的指针),并且调用{{1}永远不是一个好主意。两次在同一个指针上。
它是否仅释放指针地址,或者指向的地址也被解除分配?
当您从分配器请求内存块时,您可以指定所需块的大小。分配器跟踪块的大小,以便在释放块时,它知道起始地址和块大小。当您致电free()
时,free(p)
指向的区块将被解除分配;指针p
本身没有任何反应。
另外,如果int * p实际上是指向int?
数组的指针,该怎么办?
C中的数组是一个连续的内存块,因此指向数组第一个元素的指针也是指向整个块的指针。释放该块将正确地释放整个阵列。
我非常渴望最终理解这一点,我非常感谢任何帮助!
在C中有许多关于内存分配的好页面,您应该阅读这些页面以获得更详细的理解。你可以从一个地方开始使用GNU C Library manual section on memory allocation。
如上所述和其他答案中所述,分配器的实际行为取决于实现。您的代码不应该对内存分配如何工作超出标准库中记录的内容有任何特殊的期望,即调用p
,malloc()
等来获取内存块,并调用{{1当你完成它以便它可以重复使用时给它。
答案 1 :(得分:1)
malloc
和free
做任何他们想做的事。他们预期的行为是malloc
在动态内存中分配一个所需大小的块并返回指向它的指针。 free
必须能够接收一个这样的指针并正确地释放该块。他们如何跟踪块大小是无关紧要的。
int *p
指向int
s数组的指针吗?也许。如果为多个int
分配了足够的空间,是的。
答案 2 :(得分:0)
计算机中存在固定且有限的内存,每个人都想要一些内存。操作系统负责将所有权分配给内存并跟踪所有内容,以确保没有人与其他任何人混淆。
当您要求malloc()
的内存时,您要求系统(C运行时和操作系统)为您提供现在您的内存块的地址。你可以自由地写它并随意读取它,并且系统承诺在你拥有它时没有其他人会搞乱它。当你用free()
取消分配它时,内存本身没有任何变化,它就不再是你的了。它会发生什么事与你无关。系统可以保留它以供将来分配,它可以将其提供给其他一些过程。
有关这种情况的详细信息因系统而异,但它们实际上与程序员无关(除非您是编写malloc
/ free
代码的人)。只需在你的记忆中使用记忆,并保持你的手,而不是。