- 什么是堆叠和堆叠?
- 他们在电脑记忆中身处何方?
- 它们在多大程度上受到操作系统或语言运行时间的控制?
- 其范围是什么?
- 是什么决定了它们的大小?
- 是什么让一个更快?
当前回答
简单的说, 堆栈是创建本地变量的地方。 另外, 每次你调用一个子常规, 程序计数器( 指针到下一个机器指令) 和任何重要的登记器, 有时参数会被推到堆叠上。 然后, 子常规内的任何本地变量都会被推到堆叠上( 并在那里使用 ) 。 当子常规完成后, 所有的东西都会从堆叠上跳出来。 PC 和注册数据都会得到并放回原位, 这样您的程序就可以继续其快乐的方式 。
堆积是用( 明确的“ 新 ” 或“ 分配 ” 调用 ” 调用 ) 来分配记忆的动态空间。 它是一个特殊的数据结构, 可以跟踪大小不一的记忆区块及其分配状况 。
在“古典”系统中,内存记录仪被设置得非常清晰,使堆叠指针从记忆的底部开始,堆积指针从顶部开始,它们相互向上发展。如果它们重叠,你就退出内存。虽然这与现代多轨操作系统不起作用。每条线必须有自己的堆叠,并且它们可以动态地生成。
其他回答
许多答案作为概念是正确的,但我们必须指出,硬件(即微处理器)需要堆叠,才能调用子程序(集合语言的CALL)。 (OOP的家伙会称之为它)。方法)
在堆叠上,您保存返回地址, 并呼叫 push / ret pop 由硬件直接管理 。
您可以使用堆栈来设定通过参数. 即使比使用登记册要慢( 微处理器大师会说, 还是一本好的 1980s BIOS 书...) 。
- 没有堆叠无 无微处理器可以工作。 (我们无法想象一个程序, 即使是以组装语言, 没有子例程/功能)
- (一个集会语言方案可以工作,因为这个语言方案是一个OS概念,作为cloc,即OS/Lib呼叫。)
堆叠使用速度更快, 如下:
- 硬件,甚至推/棒子都是非常有效的。
- 商场需要进入内核模式,使用锁/气压(或其他同步原始物),执行一些代码,并管理一些跟踪分配情况所需的结构。
当在加载代码和数据操作系统设置后创建一个进程时, 在数据结束和基于架构的地址空间顶端堆叠后, 程序在装入代码和数据操作系统设置后启动堆放
当需要更多堆积时, OSS 将动态分配, 堆积块总是几乎毗连
请参看请见brk()
, sbrk()
和alloca()
系统在 Linux 中调用
其他人对大中风的反应也很好, 所以我要讲一些细节。
堆放和堆放不需要是单数的 。 堆放和堆放的多处常见情况是, 您在一个过程中拥有多个线条。 在此情况下, 每个线条都有自己的堆放。 您也可以有多个堆放。 例如, 某些 DLL 配置可能导致不同堆放的 DLL 分配不同的 DLL , 这就是为什么释放不同图书馆分配的内存通常是一个坏主意 。
在 C 中,您可以通过使用单花,它分配在堆叠上,而不是 Alloc,它分配在堆肥上。这个记忆不会保存在您的返回语句中,但它对刮痕缓冲很有用。
在 Windows 上做一个不使用很多内容的大型临时缓冲区不是免费的。 这是因为编译器将生成一个堆叠探测器循环, 每次输入您的函数时都会被调用, 以确保堆叠存在( 因为 Windows在堆叠的末尾使用一个单个的守护页面来检测堆叠的生长需要。 如果您访问堆叠尾端的多页内存, 您将会崩溃 ) 。 例如 :
void myfunction()
{
char big[10000000];
// Do something that only uses for first 1K of big 99% of the time.
}
堆堆叠
- 非常快速接入
- 不必明确排除可变变量
- 由CPU有效管理空间,内存不会分散
- 仅本地变量
- 对堆叠大小的限制(取决于OS)
- 变量无法调整大小
堆肥
- 可在全球范围内访问变量
- 内存大小无限制
- (相对)获取较慢
- 没有保证有效使用空间的保证,随着时间推移,记忆可能会变得支离破碎,因为分配了记忆区块,然后释放了
- 您必须管理内存( 您负责分配和释放变量) 。
- 可使用 elloc () 调整变量大小
堆叠当您调用函数时,该函数的参数加上一些其他间接费用被放在堆栈中。有些信息(例如返回后将到何处)也存储在那里。当您在函数中声明变量时,该变量也分布在堆栈中。
拆分堆栈很简单, 因为您总是按照您分配的反向顺序进行排列。 在输入函数时添加堆叠材料, 当退出时相应数据将被删除。 这意味着您倾向于留在堆叠的小区域内, 除非您调用许多函数来调用其他函数( 或创建循环解决方案 ) 。
堆肥堆积是一个通用的名称, 用于您将创建的数据放在哪里 。 如果您不知道您的程序要创建多少宇宙飞船, 您可能会使用新的( 或商略或等效的) 操作员来创建每艘宇宙飞船 。 此分配将会停留一段时间, 因此我们很可能释放的东西, 与我们创建的顺序不同 。
因此,堆积要复杂得多,因为最终会出现一些未使用的内存区域,这些区域与块状的内存间断 — — 内存会变得支离破碎。 找到您需要的大小的自由内存是一个困难的问题。 这就是为什么应该避免堆积(尽管它仍然经常被使用 ) 。
执行 执行 执行堆叠和堆叠的操作通常要到运行时间/操作系统。 通常游戏和其他功能至关重要的应用程序会创造自己的内存解决方案,从堆叠中抓取大量内存,然后在内部将内存分离出来,以避免依赖操作系统进行内存。
只有当你的记忆用法与常规有很大不同时, 也就是在游戏中, 在一个巨大的操作中加载一个水平, 并且可以在另一个巨大的操作中将整个批量扔掉时, 这才是实际的。
内存物理位置这比你想的要少 因为一种技术叫做虚拟内存这使得您的程序认为您可以访问某位地址, 物理数据在其他地方( 甚至是硬盘上! ) 。 您获得的堆叠地址随着您的呼叫树越深, 顺序越大。 堆放的地址是不可预知的( 具体化) , 坦率地说并不重要 。