*是否可以在分配的内存上使用free()?
我正在学习计算机工程,并且我有一些电子课程。 我从我的两位教授(这些课程中)听说,可以避免使用free()
函数(在malloc()
, calloc()
等之后),因为分配的内存空间可能不会再使用分配其他内存。 也就是说,例如,如果您分配4个字节然后释放它们,您将有4个字节的空间可能不会再分配:您将有一个漏洞。
我认为这很疯狂:你不能在没有释放的情况下在堆上分配内存的情况下使用非玩具程序。 但是我没有足够的知识来解释为什么它对每个malloc()
必须有一个free()
。
所以:在任何情况下可以使用malloc()
而不使用free()
? 如果不是的话,我该如何解释给我的教授呢?
简单:只要阅读几乎任何半认真的malloc()/free()
实现的源代码。 通过这个,我的意思是处理调用工作的实际内存管理器。 这可能在运行时库,虚拟机或操作系统中。 当然,代码在所有情况下都不能同等访问。
确保内存不碎裂,通过将相邻的孔连接到较大的孔中,非常常见。 更严重的分配器使用更严重的技术来确保这一点。
因此,让我们假设您执行三次分配和取消分配,并按以下顺序在内存中分配块:
+-+-+-+
|A|B|C|
+-+-+-+
单个分配的大小并不重要。 然后你释放第一个和最后一个,A和C:
+-+-+-+
| |B| |
+-+-+-+
当你最终释放B时,你(最初至少在理论上)最终得到:
+-+-+-+
| | | |
+-+-+-+
这可以被分解为正义
+-+-+-+
| |
+-+-+-+
即一个较大的空闲块,没有碎片。
请参考:
heap4.c
代码的这些注释。 其他的答案已经很好地解释了malloc()
和free()
实际实现确实将漏洞合并(碎片整理)为更大的空闲块。 但即使情况并非如此,放弃free()
仍然是一个坏主意。
事情是,你的程序只是分配(并且想要释放)这4个字节的内存。 如果要运行很长一段时间,很可能需要重新分配4个字节的内存。 所以即使这4个字节永远不会合并成一个更大的连续空间,它们仍然可以被程序本身重新使用。
这完全是无稽之谈,例如有许多不同的malloc
实现,有些试图让堆更有效率,比如Doug Lea或者这个。