- 什么是堆叠和堆叠?
- 他们在电脑记忆中身处何方?
- 它们在多大程度上受到操作系统或语言运行时间的控制?
- 其范围是什么?
- 是什么决定了它们的大小?
- 是什么让一个更快?
当前回答
堆栈基本上是一个容易获取的内存,仅将它的项目管理为-井-堆叠。事先知道大小的项目可以进入堆叠。数字、字符串、布林亚人的情况就是如此。
缩略堆积是您无法预先确定准确大小和结构的物品的内存。由于天体和阵列可以在运行时变异和变化,它们必须进入堆积。
资料来源:学员人数
其他回答
其他人对大中风的反应也很好, 所以我要讲一些细节。
堆放和堆放不需要是单数的 。 堆放和堆放的多处常见情况是, 您在一个过程中拥有多个线条。 在此情况下, 每个线条都有自己的堆放。 您也可以有多个堆放。 例如, 某些 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.
}
您可以用堆叠做一些有趣的事情。 例如, 您的函数像单花(假设你能够通过有关其使用的大量警告) 这是一种专门用堆叠而不是堆叠来记忆的 中转器形式。
也就是说, 堆叠式的记忆错误是我经历过的最糟糕的记忆错误。 如果您使用堆积式内存, 并超越了分配区块的界限, 您就有一个很好的机会触发断段断层断层。 ( 不是100%: 您的区块可能附带地与先前分配的区块毗连 。 ) 但是由于堆叠上创建的变量总是相互连结, 边框中的写法可以改变另一个变量的值。 我了解到, 只要我感到我的程序不再遵守逻辑法则, 它可能就是缓冲溢出 。
许多答案作为概念是正确的,但我们必须指出,硬件(即微处理器)需要堆叠,才能调用子程序(集合语言的CALL)。 (OOP的家伙会称之为它)。方法)
在堆叠上,您保存返回地址, 并呼叫 push / ret pop 由硬件直接管理 。
您可以使用堆栈来设定通过参数. 即使比使用登记册要慢( 微处理器大师会说, 还是一本好的 1980s BIOS 书...) 。
- 没有堆叠无 无微处理器可以工作。 (我们无法想象一个程序, 即使是以组装语言, 没有子例程/功能)
- (一个集会语言方案可以工作,因为这个语言方案是一个OS概念,作为cloc,即OS/Lib呼叫。)
堆叠使用速度更快, 如下:
- 硬件,甚至推/棒子都是非常有效的。
- 商场需要进入内核模式,使用锁/气压(或其他同步原始物),执行一些代码,并管理一些跟踪分配情况所需的结构。
堆堆叠
- 非常快速接入
- 不必明确排除可变变量
- 由CPU有效管理空间,内存不会分散
- 仅本地变量
- 对堆叠大小的限制(取决于OS)
- 变量无法调整大小
堆肥
- 可在全球范围内访问变量
- 内存大小无限制
- (相对)获取较慢
- 没有保证有效使用空间的保证,随着时间推移,记忆可能会变得支离破碎,因为分配了记忆区块,然后释放了
- 您必须管理内存( 您负责分配和释放变量) 。
- 可使用 elloc () 调整变量大小
短短
一个堆叠用于静态内存分配,一个堆叠用于动态内存分配,两者都存储在计算机的内存记录中。
详细细节
堆叠
堆栈是一个“ LIFO ” (最后的, 首先是) 数据结构, 由 CPU 相当密切地管理和优化。 函数每次声明一个新的变量时, 它就会被“ 挤压” 到堆栈。 然后, 每次函数退出, 所有被该函数推到堆栈的变量都会被解开( 也就是说, 它们会被删除 ) 。 一旦一个堆叠变量被解开, 内存区域就会被其他堆叠变量所利用 。
使用堆叠存储变量的优点是存储存储器的内存为您所管理。 您不需要手动分配内存, 也无需在不再需要时解开内存。 此外, 因为 CPU 组织堆叠内存的效率非常高, 读写到堆叠变量的速度非常快 。
更多可以找到在这里.
堆肥
您计算机的存储器中, 堆积是一个区域, 没有自动为您管理, 也没有由 CPU 进行严格管理。 它是一个更自由的存储区( 并且更大 ) 。 要在堆积上分配存储器, 您必须使用 C 函数内嵌的 malloc () 或 calloc () 。 一旦您在堆积上分配了存储器, 您就有责任使用自由的( ) 来在不再需要该存储器时处理该存储器 。
如果您不这样做, 您的程序将会有所谓的内存泄漏。 也就是说, 堆堆上的内存仍将被搁置( 并且无法用于其它进程 ) 。 正如我们在调试部分看到的那样, 有一个工具被称为Valgrind Valgrind Valgrind 瓦格林它可以帮助你发现内存漏。
与堆叠不同, 堆积的大小没有变量大小限制( 除了您的计算机的明显物理限制之外 ) 。 堆积的内存读和书写要慢一点, 因为人们必须用指针来访问堆积的内存。 我们很快会讨论指针问题 。
与堆叠不同的是,在堆积上创建的变量可以被任意函数进入,在您的程序中的任何地方。堆积变量在范围上基本上是全球性的。
更多可以找到在这里.
堆栈上分配的变量直接存储到内存中, 访问此内存的时间非常快, 程序编译时会处理其分配问题。 当函数或方法调用另一个函数, 转而调用另一个函数等时, 所有这些函数的履行将一直暂停, 直到最后一个函数返回其值。 堆栈总是保留在 LIFO 的顺序中, 最新的保留区块总是要解开的下一个块块。 这样可以非常简单地跟踪堆叠, 从堆叠中释放一个块只是调整一个指针而已 。
堆积上分配的变量的内存在运行时间分配, 访问此内存的时间稍慢一点, 但堆积大小仅受虚拟内存大小的限制。 堆积的元素不互相依赖, 随时可以随机访问。 您可以随时分配块块, 并随时释放它。 这让跟踪堆积中哪些部分在任何特定时间分配或自由, 变得更加复杂 。
如果您确切知道在编译时间之前需要分配多少数据, 您可以使用堆叠, 而它并不太大。 如果您不知道运行时需要多少数据, 或者需要分配很多数据, 您可以使用堆叠 。
在一个多轨情况下, 每串线索将有自己的完全独立的堆叠, 但是它们会共享堆叠 。 堆叠是特定的线条, 堆叠是特定的应用程序 。 堆叠很重要, 在例外处理和丝线处决中需要考虑 。
每一串线索都有堆叠, 而通常应用程序只有一堆(尽管不同类型分配的多堆线索并不罕见) 。
运行时,如果应用程序需要更多堆积,它可以从自由存储中分配内存,如果堆叠需要内存,它可以从为应用程序分配的内存中分配内存。
来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来你的问题的答案.
它们在多大程度上受到操作系统或语言运行时间的控制?
当线索创建时, OS 会为每个系统级线索分配书架。 通常情况下, OS 会被语言运行时间调用来分配应用程序的堆积 。
更多可以找到在这里.
其范围是什么?
上方已经给出了 。
“如果你确切知道在编译时间之前你需要分配多少数据,你可以使用堆叠。它并不太大。如果你不知道运行时你需要多少数据,或者你需要分配很多数据,你可以使用堆叠。”
更多可见于在这里.
是什么决定了每个孩子的大小?
堆叠的大小由OS当创建线索时。 程序启动时会设置堆积的大小, 但随着空间需要, 堆积会变大( 分配器要求操作系统的内存更多 ) 。
是什么让一个更快?
堆叠分配速度要快得多, 因为它实际上所做的就是移动堆叠指针。 使用记忆池, 您可以从堆积分配中获取相似的性能, 但是这伴随着一个稍微增加的复杂性和它自己的头痛。
此外,堆叠对堆积不仅是一种绩效考量;它也告诉你很多关于物体预期寿命的情况。
详情可从在这里.