C++ 堆栈内存与堆内存

C++ 堆栈内存与堆内存,c++,memory,C++,Memory,可能重复: 我正在C++编程,我一直想知道堆栈内存和堆内存到底是什么。我所知道的是,当我调用new时,我会从heap中获取内存。若创建局部变量,我将从堆栈中获取内存。经过对internet的一些研究,最常见的答案是堆栈内存是临时的,而堆内存是永久的 堆栈和堆内存模型是操作系统还是计算机体系结构的概念?所以其中一些可能不遵循堆栈和堆内存模型,或者所有的都遵循它 堆栈和堆内存是对虚拟内存(可能在磁盘和RAM之间交换内存)的内存模型的抽象。那么堆栈和堆内存在物理上可能是RAM还是磁盘?那么,堆分配似

可能重复:

我正在C++编程,我一直想知道堆栈内存和堆内存到底是什么。我所知道的是,当我调用new时,我会从heap中获取内存。若创建局部变量,我将从堆栈中获取内存。经过对internet的一些研究,最常见的答案是堆栈内存是临时的,而堆内存是永久的

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

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

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

另外,如果进程耗尽了分配的堆栈内存或堆内存,会发生什么情况


谢谢

这是一种语言抽象——有些语言两者都有,有些有,有些没有


在C++的情况下,代码不在堆栈或堆中运行。通过重复调用

new
在循环中分配内存,而不调用
delete
释放内存,可以测试堆内存耗尽时会发生什么情况但在执行此操作之前进行系统备份

堆栈内存是通过CPU的堆栈寄存器可访问的内存范围。堆栈被用作在汇编语言中实现“跳转子程序”-“返回”代码模式的一种方式,也被用作实现硬件级中断处理的一种手段。例如,在中断期间,堆栈用于存储各种CPU寄存器,包括状态(表示操作结果)和程序计数器(中断发生时CPU在程序中的位置)

堆栈内存在很大程度上是常规CPU设计的结果。它的分配/释放速度很快,因为它严格地说是后进先出的设计。这是一个简单的移动操作和堆栈寄存器上的减量/增量操作

堆内存只是加载程序并分配堆栈内存后剩下的内存。它可能(也可能不)包括全局变量空间(这是一个惯例)


现代抢占式多任务操作系统的虚拟内存和内存映射设备使实际情况更加复杂,但这是堆栈与堆的简单概括。

< P> C++中,堆栈内存是本地变量存储/构建的地方。堆栈还用于保存传递给函数的参数

堆栈非常类似于std::stack类:将参数推送到堆栈上,然后调用函数。然后,函数知道可以在堆栈的末尾找到它期望的参数。同样,函数可以将局部变量推到堆栈上,并在从函数返回之前将它们从堆栈中弹出。(警告-编译器优化和调用约定都意味着事情并非如此简单)

我建议从较低的层次来理解堆栈。很少,如果有,你会考虑任何类型的手动堆栈操作从C++ + < /P> 一般来说,堆栈是首选的,因为它通常位于CPU缓存中,因此涉及存储在堆栈上的对象的操作往往更快。然而,堆栈是一个有限的资源,不应该用于任何大的东西。堆栈内存不足称为内存不足。这是一件很严重的事情,但除非你有一个疯狂的递归函数或类似的东西,否则你真的不应该遇到它


堆内存就像rskar所说的那样。一般来说,分配给新对象的C++对象或用MALLC类分配的内存块最终会堆起来。堆内存几乎总是必须手动释放,尽管您确实应该使用智能指针类或类似类来避免需要记住这样做。堆内存不足可能(将?)导致std::bad_alloc。

在尝试填充堆之前“进行系统备份”?你在什么平台上,MS-DOS?@larsman但你是否取消了对用户进程的限制?你在窗户上试过了吗?对于我们大多数Unix用户来说,“必须重新启动”是被解雇的下一步。@Unaperson:所有系统(Linux、Mac OS X、OpenBSD)都有默认限制。不,我从不在窗户上尝试任何沉重的东西,我讨厌清理碎玻璃;)@乌纳佩尔森:啊,对。我没有在生产服务器上运行此类测试的习惯,我相信我的本地计算中心不会取消HPC集群的限制:)@TonyK这将是真实的世界(如果出现问题,你必须付费),而不是你生活的快乐世界,我猜。@meagar这确实提出了一些你链接到的问题中没有提到的问题。这在很多方面都是错误的。在我所知道的任何体系结构上,“堆栈内存”和“堆内存”之间通常没有任何区别。两者都可以通过堆栈指针、索引寄存器或其他方式访问。堆栈指针和索引寄存器都可以任意更改,以访问进程可用的任何内存。@Unaperson:RAM就是RAM,SP当然可以更改和分配。“堆栈内存”更多的是一个意图或角色的术语——不一定是专门的硬件。顺便说一句,在6502的例子中,你的堆栈确实卡在了第1页(字节256到511)。@rskar确实是。1984年,我在6502汇编程序中编写了KERMIT协议的一个实现,并在BBC Micro上进行了完整的VT100终端仿真(对于Z80程序员来说,这不是一个愉快的经历),因此我知道我在这里所说的。@rskar对于大多数体系结构,堆栈内存和普通内存之间没有区别。即使在6502上,您也可以(有时不得不)执行