堆栈内存与堆内存

时间:2011-04-29 19:09:03

标签: c++ memory

  

可能重复:
  What and where are the stack and heap

我使用C ++编程,我总是想知道堆栈内存与堆内存到底是什么。我所知道的就是当我调用new时,我会从堆中获取内存。如果创建局部变量,我会从堆栈中获取内存。经过对互联网的一些研究,最常见的答案是堆栈内存是临时的,堆内存是永久性的。

堆栈和堆内存模型是操作系统或计算机体系结构的概念吗?所以有些可能不遵循堆栈和堆内存模型或所有它们都遵循它?

堆栈和堆内存是虚拟内存的内存模型的抽象(可能在磁盘和RAM之间交换内存)。堆栈和堆内存在物理上可能是RAM还是磁盘?那么堆分配似乎比堆栈对应慢的原因是什么?

此外,主程序将在堆栈或堆中运行吗?

此外,如果进程耗尽了堆栈内存或堆内存,会发生什么?

由于

3 个答案:

答案 0 :(得分:49)

在C ++中,堆栈内存是存储/构造局部变量的地方。堆栈还用于保存传递给函数的参数。

堆栈就像std :: stack类一样,你将参数推送到它上面然后调用一个函数。然后,该函数知道它可以在堆栈末尾找到的参数。同样,该函数可以将locals推入堆栈并在从函数返回之前将其弹出。 (警告 - 编译器优化和调用约定都意味着事情并非如此简单)

从低级别开始最好理解堆栈,我建议使用此链接Art of Assembly - Passing Parameters on the Stack。很少有人会考虑使用C ++进行任何类型的手动堆栈操作。

一般来说,堆栈是首选,因为它通常位于CPU缓存中,因此涉及存储在其上的对象的操作往往更快。但是堆栈是有限的资源,不应该用于任何大的。耗尽堆栈内存称为Stack buffer overflow。这是一个严肃的事情,但你真的不应该遇到一个,除非你有一个疯狂的递归函数或类似的东西。

堆内存就像rskar所说的那样。一般来说,在使用new分配的C ++对象中,或者使用malloc等分配的内存块最终会在堆上。堆内存几乎总是必须手动释放,但你应该重新使用智能指针类或类似的东西,以避免需要记住这样做。耗尽堆内存可以(将?)导致std :: bad_alloc。

答案 1 :(得分:30)

堆栈存储器具体是可通过CPU的堆栈寄存器访问的存储器范围。 Stack用作实现汇编语言中“Jump-Subroutine” - “Return”代码模式的一种方式,也是实现硬件级中断处理的一种方法。例如,在中断期间,堆栈用于存储各种CPU寄存器,包括Status(表示操作结果)和Program Counter(中断发生时程序中的CPU)。

堆栈内存是通常的CPU设计的结果。分配/解除分配的速度很快,因为它严格地是后进/先出设计。在堆栈寄存器上移动操作和递减/递增操作很简单。

堆内存只是加载程序并分配堆栈内存后遗留的内存。它可能(或可能不)包含全局变量空间(这是惯例问题)。

具有虚拟内存和内存映射设备的现代先发制人多任务操作系统使实际情况更加复杂,但简而言之就是Stack vs Heap。

答案 2 :(得分:2)

这是一种语言抽象 - 有些语言既有一种语言,有些语言也没有。

对于C ++,代码不会在堆栈或堆中运行。您可以通过重复调用new在循环中分配内存而不调用delete来释放它来测试堆内存耗尽时会发生什么。 但在执行此操作之前进行系统备份