堆内存到底是什么?
每当调用 malloc 时,都会从称为堆的东西中分配内存。堆到底在哪里。我知道主存中的程序分为存在程序语句的指令段,存储全局数据的数据段和存储局部变量和相应函数参数的堆栈段。现在,堆呢?
堆内存到底是什么?
每当调用 malloc 时,都会从称为堆的东西中分配内存。堆到底在哪里。我知道主存中的程序分为存在程序语句的指令段,存储全局数据的数据段和存储局部变量和相应函数参数的堆栈段。现在,堆呢?
堆是进程地址空间的一部分。堆可以增长或缩小;你通过调用brk(2)
or来操作它sbrk(2)
。这实际上就是malloc(3)
这样做的。
从堆中分配比在堆栈上分配内存更方便,因为它在调用例程返回后仍然存在;因此,您可以调用例程,例如funcA()
,分配一堆内存并用一些东西填充它;funcA()
该内存在返回后仍然有效。如果funcA()
分配了一个本地数组(在堆栈上),那么当funcA()
返回时,堆栈上的数组就消失了。
使用堆的一个缺点是,如果您忘记释放堆分配的内存,您可能会耗尽它。未能释放堆分配的内存(例如,未能free()
从 获取内存malloc()
)有时称为内存泄漏。
与仅在堆栈上分配本地数组/结构/任何内容相比,堆的另一个不错的功能是,您会获得一个返回值,说明您的分配是否成功;如果你尝试在堆栈上分配一个本地数组并且你用完了,你不会得到错误代码;通常,您的线程将被简单地中止。
堆与栈截然相反。堆是一个可以动态使用的大型内存池——它也被称为“自由存储”。这是不是自动管理的内存——您必须显式分配(使用诸如 malloc 之类的函数)和释放(例如释放)内存。完成后未能释放内存将导致所谓的内存泄漏 - 仍然“正在使用”的内存,并且对其他进程不可用。与堆栈不同,除了机器内存的物理大小之外,堆的大小(或它创建的变量)通常没有限制。在堆上创建的变量可以在程序的任何地方访问。
哦,堆内存需要你使用指针。
堆的总结:
归功于 Craftofcoding
基本上,内存被程序的需要消耗掉之后,剩下的就是堆了。在 C 语言中,这将是计算机可用的内存,而对于虚拟机,它会比这更少。
但是,这是可以在运行时使用的内存,因为您的程序需要动态内存。
您可能想查看此以获取更多信息:
通读一遍,这实际上超出了 C 的范围。C 没有指定后面有堆malloc
;它可以很容易地称为链表;按照惯例,您只是将其称为堆。
标准保证malloc
将返回指向具有动态存储持续时间的对象的指针,而您的堆只是一种有助于提供这种存储持续时间的数据结构。这是常见的选择。尽管如此,编写堆的开发人员已经认识到它可能不是堆,因此例如在 POSIX 手册中您不会看到对术语堆的引用。malloc
超出标准 C 领域的其他内容包括机器代码二进制文件的详细信息,编译后不再是 C 源代码。布局细节虽然很典型,但都是特定于实现的,而不是特定于 C 的。
heap或任何用于说明分配的簿记数据结构是在运行时生成的;正如malloc
所谓的那样,新条目(可能)被添加到其中,并且正如free
所谓的,新条目(再次,可能)从中删除。
因此,对于使用 分配的对象,通常不需要在机器代码二进制文件中有一个部分malloc
,但是在某些情况下,应用程序是独立交付的,烘焙到微处理器中,在其中一些情况下,您可能会发现闪存或其他非易失性内存可能会保留用于该用途。