关于c ++:堆栈与堆栈和堆与堆的关系

a stack vs the stack and a heap vs the heap

我正在为我的数据组织期末考试而学习,我会翻阅成堆的资料,因为我知道它们会在期末考试中,我需要知道它们之间的区别。我知道什么是堆栈,什么是堆栈。

但我对什么是堆栈和什么是堆栈感到困惑。

堆栈是内存存储在RAM中的一个地方,如果内存耗尽,就会发生堆栈溢出。对象默认存储在这里,当对象超出范围时,它会重新分配内存,而且速度更快。

堆是内存存储在RAM中的一个地方,如果它耗尽了空间,操作系统将为它分配更多的内存。对于要存储在堆上的对象,需要使用、new、运算符来通知它,并且只有在通知时才会解除分配。碎片问题可能会发生,它比堆栈慢,并且更好地处理大量内存。

但是什么是堆栈,什么是堆栈?这是存储内存的方式吗?例如,静态数组或静态向量是堆栈类型,而动态数组、链接列表是堆类型?

谢谢大家!


我不会进入虚拟内存(如果你想的话,可以读一下),所以让我们简化一下,假设你有一些大小的RAM。

您有静态初始化数据的代码,还有一些静态未初始化数据(C++中的静态方式,如全局VARS)。你有你的密码。

当您编译某个代码时,编译器(和链接器)将按以下方式组织代码并将其转换为机器代码(字节代码、1和0):

二进制文件(和对象文件)被组织成段(RAM的一部分)。

首先是数据段。这是包含初始化变量值的段。所以如果你有变量,比如int a=3, b = 4,它们将进入数据段(RAM的4个字节包含0000003H,其它4个字节包含00000004H,十六进制记数法)。它们是连续存储的。

然后是代码段。所有代码都被转换成机器代码(1s和0s),并连续存储在这个段中。

然后是BSS段。存在未初始化的全局变量(所有未初始化的静态变量)。

然后是堆栈段。这是为堆栈保留的。堆栈大小默认由操作系统决定。你可以改变这个值,但我现在不想谈这个了。所有局部变量都在这里。当您调用某个函数时,首先将func参数推送到堆栈,然后返回地址(当您退出函数时返回的位置),然后将一些计算机寄存器推送到这里,最后,函数中声明的所有局部变量在堆栈上获得它们的保留空间。

还有堆段。这是RAM的一部分(大小也由操作系统决定),对象和数据使用操作符new存储。

然后将所有的段依次堆放在其他数据、代码、BSS、堆栈、堆中。还有一些其他的段,但是它们在这里不感兴趣,并且由操作系统加载到RAM中。二进制文件还有一些头文件,其中包含代码从哪个位置(内存中的地址)开始的信息。

总之,它们都是RAM的一部分,因为正在执行的所有操作都被加载到RAM中(不能在只读存储器中),也不能在HDD中,因为HDD只是用来存储文件。


"堆栈"和"堆"是程序或操作系统以特定方式使用的内存块。例如,调用堆栈可以保存与函数调用相关的数据,堆是专门用于动态分配空间的内存区域。

将它们与堆栈和堆数据结构进行对比。

堆栈可以看作是一个数组,其中的最后一个元素将是第一个元素。在这上面的操作称为push和pop。

堆是一种数据结构,它表示一种特殊类型的图,其中每个节点的值大于节点的子节点的值。

请注意,"堆栈"或"堆"或任何堆栈/堆数据结构对于任何给定的编程语言都是唯一的,但只是计算机科学领域的概念。


对于您来说,了解堆栈的重要内容是堆栈和函数/方法调用之间的关系。每个函数调用都在堆栈上保留空间,称为堆栈帧。此空间包含自动变量(在函数体中声明的变量)。当您退出函数时,堆栈框架及其包含的所有自动变量都将消失。

这种机制在使用CPU资源方面非常便宜,但是这些堆栈分配变量的寿命显然受到函数范围的限制。

另一方面,堆上的内存分配(对象)可以"永久"地存在,或者在不考虑程序控制流的情况下,只要您需要它们就可以存在。缺点是,由于没有自动管理这些堆分配的对象的生存期,因此必须1)自己管理生存期,或者2)使用诸如智能指针之类的特殊机制来管理这些对象的生存期。如果你弄错了,你的程序就会发生内存泄漏,或者访问可能会发生意外变化的数据。

回复:关于栈与栈的问题:当您使用多个线程时,每个线程都有一个单独的栈,这样每个线程就可以独立地进出函数/方法。大多数单线程程序只有一个栈:常用术语中的"栈"。

堆也一样。如果您有特殊的需要,可以分配多个堆,并在分配时选择应该使用哪个堆。这不太常见(比我在这里提到的更复杂的话题)。


特别是引用C++的内存模型时,堆和堆栈指的是内存区域。很容易将其与堆栈数据结构和堆数据结构混淆。然而,它们是独立的概念。

在讨论编程语言时,堆栈内存被称为"堆栈",因为它的行为类似于堆栈数据结构。堆有点用词不当,因为它不一定(或可能)使用堆数据结构。明白为什么两个不同的概念都被称为"堆"?讨论为什么C++的堆和数据结构的名称是相同的,尽管是两个不同的概念。

所以要回答你的问题,这取决于上下文。在编程语言和内存管理的上下文中,堆和堆栈指具有特定属性的内存区域。否则,它们指的是特定的数据结构。


"堆栈"的技术定义是一种后进先出(LIFO)的数据结构,在该结构中,数据被推到顶部并从顶部拉出。就像现实世界中的一堆板一样,您不会从中间或底部拉出一个,您[通常]也不会从数据结构堆栈的中间或底部拉出数据。当有人从编程的角度谈论堆栈时,它通常(但不总是)意味着硬件堆栈,由CPU中的堆栈指针寄存器控制。

就"堆"而言,从每个人都能认同的定义来看,这通常变得更加模糊。最佳定义可能是"为动态内存管理分配空间的大量可用内存"。换句话说,当您需要新内存时,无论是对于数组,还是使用新运算符创建的对象,它都来自OS为您的程序保留的堆。这是程序POV中的"堆",但只是操作系统POV中的"堆"。