栈对栈,堆对堆

a stack vs the stack and a heap vs the heap

本文关键字:      更新时间:2023-10-16

我正在为我的数据组织期末考试做准备,我要复习堆栈和堆,因为我知道它们会在期末考试中出现,我需要知道它们的区别。我知道什么是栈,什么是堆。

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

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

堆是RAM中存储内存的地方,如果它耗尽了空间,操作系统将分配更多的空间。对于要存储在堆上的对象,需要使用new操作符告诉它,并且只有在被告知时才会被释放。可能会出现碎片问题,它比Stack慢,并且可以更好地处理大量内存。

但是什么是堆栈,什么是堆呢?是记忆的存储方式吗?例如,静态数组或静态向量是堆栈类型和动态数组,链表堆类型?

谢谢大家!

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

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

堆栈可以看作是一个数组,其中最后一个进入的元素将是第一个取出的元素。这些操作称为push和pop。

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

顺便说一句,请记住"堆栈"或"堆"或任何堆栈/堆数据结构对于任何给定的编程语言都是独特的,但它们只是计算机科学领域的概念。

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

你的代码中有静态初始化的数据,还有一些静态未初始化的数据(静态在c++中意味着全局变量)。你有你的代码。

当你编译一些东西时,编译器(和链接器)将按照以下方式组织和翻译你的代码到机器代码(字节码,1和0):

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

首先你有数据段。这是包含初始化变量值的段。因此,如果你有变量,即int a=3, b = 4,它们将进入DATA段(4字节的RAM包含00000003h,其他4字节包含000000004h,十六进制符号)。它们是连续存储的。然后你有代码段。所有代码都被翻译成机器码(1和0)并连续存储在此段中。然后你有BSS段。还有未初始化的全局变量(所有未初始化的静态变量) 然后你有STACK段。这是为堆栈保留的。默认情况下,堆栈大小由操作系统决定。你可以改变这个值,但我现在不讨论这个。所有的局部变量都在这里。当你调用某个函数时,首先将函数参数压入堆栈,然后返回地址(退出函数时返回的地址),然后将一些计算机寄存器压入这里,最后在函数中声明的所有局部变量在堆栈上获得保留空间。

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

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

所以简而言之,它们都是RAM的一部分,因为所有正在执行的内容都加载到RAM中(不能在ROM(只读)中),也不是HDD,因为HDD只是用于存储文件。

当特别提到c++的内存模型时,堆和堆栈指的是内存区域。这很容易与堆栈数据结构和堆数据结构混淆。然而,它们是不同的概念。

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

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

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

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

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

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

另一方面,堆上的内存分配(对象)可以"永远"存在,或者只要你需要它们,而不需要考虑程序的控制流。缺点是,由于无法对这些堆分配的对象进行自动生命周期管理,因此必须要么1)自己管理生命周期,要么2)使用智能指针等特殊机制来管理这些对象的生命周期。如果你做错了,你的程序有内存泄漏,或者访问的数据可能会意外改变。

回复:你关于堆栈vs堆栈的问题:当你使用多个线程时,每个线程都有一个单独的堆栈,以便每个线程可以独立地进出函数/方法。大多数单线程程序只有一个堆栈:在通用术语中称为"堆栈"。

同样适用于堆。如果您有特殊需要,可以分配多个堆,并在分配时选择应该使用哪个堆。

这是一个比我在这里提到的要复杂得多的话题。
相关文章:
  • 没有找到相关文章