• 什么是堆叠和堆叠?
  • 他们在电脑记忆中身处何方?
  • 它们在多大程度上受到操作系统或语言运行时间的控制?
  • 其范围是什么?
  • 是什么决定了它们的大小?
  • 是什么让一个更快?

当前回答

许多答案作为概念是正确的,但我们必须指出,硬件(即微处理器)需要堆叠,才能调用子程序(集合语言的CALL)。 (OOP的家伙会称之为它)。方法)

在堆叠上,您保存返回地址, 并呼叫 push / ret pop 由硬件直接管理 。

您可以使用堆栈来设定通过参数. 即使比使用登记册要慢( 微处理器大师会说, 还是一本好的 1980s BIOS 书...) 。

  • 没有堆叠无 无微处理器可以工作。 (我们无法想象一个程序, 即使是以组装语言, 没有子例程/功能)
  • (一个集会语言方案可以工作,因为这个语言方案是一个OS概念,作为cloc,即OS/Lib呼叫。)

堆叠使用速度更快, 如下:

  • 硬件,甚至推/棒子都是非常有效的。
  • 商场需要进入内核模式,使用锁/气压(或其他同步原始物),执行一些代码,并管理一些跟踪分配情况所需的结构。

其他回答

短短

一个堆叠用于静态内存分配,一个堆叠用于动态内存分配,两者都存储在计算机的内存记录中。


详细细节

堆叠

堆栈是一个“ LIFO ” (最后的, 首先是) 数据结构, 由 CPU 相当密切地管理和优化。 函数每次声明一个新的变量时, 它就会被“ 挤压” 到堆栈。 然后, 每次函数退出, 所有被该函数推到堆栈的变量都会被解开( 也就是说, 它们会被删除 ) 。 一旦一个堆叠变量被解开, 内存区域就会被其他堆叠变量所利用 。

使用堆叠存储变量的优点是存储存储器的内存为您所管理。 您不需要手动分配内存, 也无需在不再需要时解开内存。 此外, 因为 CPU 组织堆叠内存的效率非常高, 读写到堆叠变量的速度非常快 。

更多可以找到在这里.


堆肥

您计算机的存储器中, 堆积是一个区域, 没有自动为您管理, 也没有由 CPU 进行严格管理。 它是一个更自由的存储区( 并且更大 ) 。 要在堆积上分配存储器, 您必须使用 C 函数内嵌的 malloc () 或 calloc () 。 一旦您在堆积上分配了存储器, 您就有责任使用自由的( ) 来在不再需要该存储器时处理该存储器 。

如果您不这样做, 您的程序将会有所谓的内存泄漏。 也就是说, 堆堆上的内存仍将被搁置( 并且无法用于其它进程 ) 。 正如我们在调试部分看到的那样, 有一个工具被称为Valgrind Valgrind Valgrind 瓦格林它可以帮助你发现内存漏。

与堆叠不同, 堆积的大小没有变量大小限制( 除了您的计算机的明显物理限制之外 ) 。 堆积的内存读和书写要慢一点, 因为人们必须用指针来访问堆积的内存。 我们很快会讨论指针问题 。

与堆叠不同的是,在堆积上创建的变量可以被任意函数进入,在您的程序中的任何地方。堆积变量在范围上基本上是全球性的。

更多可以找到在这里.


堆栈上分配的变量直接存储到内存中, 访问此内存的时间非常快, 程序编译时会处理其分配问题。 当函数或方法调用另一个函数, 转而调用另一个函数等时, 所有这些函数的履行将一直暂停, 直到最后一个函数返回其值。 堆栈总是保留在 LIFO 的顺序中, 最新的保留区块总是要解开的下一个块块。 这样可以非常简单地跟踪堆叠, 从堆叠中释放一个块只是调整一个指针而已 。

堆积上分配的变量的内存在运行时间分配, 访问此内存的时间稍慢一点, 但堆积大小仅受虚拟内存大小的限制。 堆积的元素不互相依赖, 随时可以随机访问。 您可以随时分配块块, 并随时释放它。 这让跟踪堆积中哪些部分在任何特定时间分配或自由, 变得更加复杂 。

Enter image description here

如果您确切知道在编译时间之前需要分配多少数据, 您可以使用堆叠, 而它并不太大。 如果您不知道运行时需要多少数据, 或者需要分配很多数据, 您可以使用堆叠 。

在一个多轨情况下, 每串线索将有自己的完全独立的堆叠, 但是它们会共享堆叠 。 堆叠是特定的线条, 堆叠是特定的应用程序 。 堆叠很重要, 在例外处理和丝线处决中需要考虑 。

每一串线索都有堆叠, 而通常应用程序只有一堆(尽管不同类型分配的多堆线索并不罕见) 。

Enter image description here

运行时,如果应用程序需要更多堆积,它可以从自由存储中分配内存,如果堆叠需要内存,它可以从为应用程序分配的内存中分配内存。

甚至提供更详细的资料在这里在这里.


来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来你的问题的答案.

它们在多大程度上受到操作系统或语言运行时间的控制?

当线索创建时, OS 会为每个系统级线索分配书架。 通常情况下, OS 会被语言运行时间调用来分配应用程序的堆积 。

更多可以找到在这里.

其范围是什么?

上方已经给出了 。

“如果你确切知道在编译时间之前你需要分配多少数据,你可以使用堆叠。它并不太大。如果你不知道运行时你需要多少数据,或者你需要分配很多数据,你可以使用堆叠。”

更多可见于在这里.

是什么决定了每个孩子的大小?

堆叠的大小由OS当创建线索时。 程序启动时会设置堆积的大小, 但随着空间需要, 堆积会变大( 分配器要求操作系统的内存更多 ) 。

是什么让一个更快?

堆叠分配速度要快得多, 因为它实际上所做的就是移动堆叠指针。 使用记忆池, 您可以从堆积分配中获取相似的性能, 但是这伴随着一个稍微增加的复杂性和它自己的头痛。

此外,堆叠对堆积不仅是一种绩效考量;它也告诉你很多关于物体预期寿命的情况。

详情可从在这里.

堆堆叠

  • 非常快速接入
  • 不必明确排除可变变量
  • 由CPU有效管理空间,内存不会分散
  • 仅本地变量
  • 对堆叠大小的限制(取决于OS)
  • 变量无法调整大小

堆肥

  • 可在全球范围内访问变量
  • 内存大小无限制
  • (相对)获取较慢
  • 没有保证有效使用空间的保证,随着时间推移,记忆可能会变得支离破碎,因为分配了记忆区块,然后释放了
  • 您必须管理内存( 您负责分配和释放变量) 。
  • 可使用 elloc () 调整变量大小

其他人对大中风的反应也很好, 所以我要讲一些细节。

  1. 堆放和堆放不需要是单数的 。 堆放和堆放的多处常见情况是, 您在一个过程中拥有多个线条。 在此情况下, 每个线条都有自己的堆放。 您也可以有多个堆放。 例如, 某些 DLL 配置可能导致不同堆放的 DLL 分配不同的 DLL , 这就是为什么释放不同图书馆分配的内存通常是一个坏主意 。

  2. 在 C 中,您可以通过使用单花,它分配在堆叠上,而不是 Alloc,它分配在堆肥上。这个记忆不会保存在您的返回语句中,但它对刮痕缓冲很有用。

  3. 在 Windows 上做一个不使用很多内容的大型临时缓冲区不是免费的。 这是因为编译器将生成一个堆叠探测器循环, 每次输入您的函数时都会被调用, 以确保堆叠存在( 因为 Windows在堆叠的末尾使用一个单个的守护页面来检测堆叠的生长需要。 如果您访问堆叠尾端的多页内存, 您将会崩溃 ) 。 例如 :

void myfunction()
{
   char big[10000000];
   // Do something that only uses for first 1K of big 99% of the time.
}

堆叠 :

  • 存储在计算机内存中 就像堆积物一样
  • 堆叠上创建的变量将超出范围, 自动进行交易 。
  • 与堆积上的变量相比,分配速度要快得多。
  • 采用实际的堆叠数据结构。
  • 存储本地数据, 返回地址, 用于通过参数 。
  • 当堆叠使用过多时(大部分来自无限重现或过深重重循环,分配量很大), 堆叠就会溢出。
  • 在堆栈上创建的数据可以不用指针使用 。
  • 如果您确切知道在编译时间之前需要分配多少数据, 并且数据并不太大, 您就会使用堆叠 。
  • 通常在程序启动时已经确定了最大尺寸 。

热量 :

  • 存储在计算机内存 和堆叠一样。
  • 在 C+++ 中, 堆积上的变量必须手动销毁, 并且绝对不能脱离范围。 数据以delete, delete[],或free.
  • 相对于堆叠上的变量, 较慢分配速度 。
  • 用于按需分配一组数据供程序使用。
  • 当有大量拨款和交易时,就有可能支离破碎。
  • 在C++ 或C++ 或C中,在堆积上生成的数据将用指针指出,并用newmalloc两者分别。
  • 如果要求分配的缓冲量太大,则可以造成分配失败。
  • 如果您不知道运行时需要多少数据, 或者需要分配大量数据, 您就会使用这种数据 。
  • 负责内存泄漏

示例:

int foo()
{
  char *pBuffer; //<--nothing allocated yet (excluding the pointer itself, which is allocated here on the stack).
  bool b = true; // Allocated on the stack.
  if(b)
  {
    //Create 500 bytes on the stack
    char buffer[500];

    //Create 500 bytes on the heap
    pBuffer = new char[500];

   }//<-- buffer is deallocated here, pBuffer is not
}//<--- oops there's a memory leak, I should have called delete[] pBuffer;

我想许多其他人 已经给了你 大多是正确的答案 这个问题。

然而,一个被忽略的细节是,“堆积”实际上可能应该被称为“免费商店 ” 。 之所以有这种区别,是因为最初的免费商店是用一个称为“binomial heap”的数据结构实施的。 因此,从早期实施中分配的麦洛克()/免费()是从堆积中分配的。 然而,在现代,大部分免费商店都是用非常精密的数据结构实施的,而不是二元式的堆积。