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

当前回答

简单的说, 堆栈是创建本地变量的地方。 另外, 每次你调用一个子常规, 程序计数器( 指针到下一个机器指令) 和任何重要的登记器, 有时参数会被推到堆叠上。 然后, 子常规内的任何本地变量都会被推到堆叠上( 并在那里使用 ) 。 当子常规完成后, 所有的东西都会从堆叠上跳出来。 PC 和注册数据都会得到并放回原位, 这样您的程序就可以继续其快乐的方式 。

堆积是用( 明确的“ 新 ” 或“ 分配 ” 调用 ” 调用 ) 来分配记忆的动态空间。 它是一个特殊的数据结构, 可以跟踪大小不一的记忆区块及其分配状况 。

在“古典”系统中,内存记录仪被设置得非常清晰,使堆叠指针从记忆的底部开始,堆积指针从顶部开始,它们相互向上发展。如果它们重叠,你就退出内存。虽然这与现代多轨操作系统不起作用。每条线必须有自己的堆叠,并且它们可以动态地生成。

其他回答

当在加载代码和数据操作系统设置后创建一个进程时, 在数据结束和基于架构的地址空间顶端堆叠后, 程序在装入代码和数据操作系统设置后启动堆放

当需要更多堆积时, OSS 将动态分配, 堆积块总是几乎毗连

请参看请见brk(), sbrk()alloca()系统在 Linux 中调用

短短

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


详细细节

堆叠

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

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

更多可以找到在这里.


堆肥

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

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

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

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

更多可以找到在这里.


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

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

Enter image description here

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

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

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

Enter image description here

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

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


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

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

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

更多可以找到在这里.

其范围是什么?

上方已经给出了 。

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

更多可见于在这里.

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

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

是什么让一个更快?

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

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

详情可从在这里.

堆叠 :

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

热量 :

  • 存储在计算机内存 和堆叠一样。
  • 在 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;

堆叠当您调用函数时,该函数的参数加上一些其他间接费用被放在堆栈中。有些信息(例如返回后将到何处)也存储在那里。当您在函数中声明变量时,该变量也分布在堆栈中。

拆分堆栈很简单, 因为您总是按照您分配的反向顺序进行排列。 在输入函数时添加堆叠材料, 当退出时相应数据将被删除。 这意味着您倾向于留在堆叠的小区域内, 除非您调用许多函数来调用其他函数( 或创建循环解决方案 ) 。

堆肥堆积是一个通用的名称, 用于您将创建的数据放在哪里 。 如果您不知道您的程序要创建多少宇宙飞船, 您可能会使用新的( 或商略或等效的) 操作员来创建每艘宇宙飞船 。 此分配将会停留一段时间, 因此我们很可能释放的东西, 与我们创建的顺序不同 。

因此,堆积要复杂得多,因为最终会出现一些未使用的内存区域,这些区域与块状的内存间断 — — 内存会变得支离破碎。 找到您需要的大小的自由内存是一个困难的问题。 这就是为什么应该避免堆积(尽管它仍然经常被使用 ) 。

执行 执行 执行堆叠和堆叠的操作通常要到运行时间/操作系统。 通常游戏和其他功能至关重要的应用程序会创造自己的内存解决方案,从堆叠中抓取大量内存,然后在内部将内存分离出来,以避免依赖操作系统进行内存。

只有当你的记忆用法与常规有很大不同时, 也就是在游戏中, 在一个巨大的操作中加载一个水平, 并且可以在另一个巨大的操作中将整个批量扔掉时, 这才是实际的。

内存物理位置这比你想的要少 因为一种技术叫做虚拟内存这使得您的程序认为您可以访问某位地址, 物理数据在其他地方( 甚至是硬盘上! ) 。 您获得的堆叠地址随着您的呼叫树越深, 顺序越大。 堆放的地址是不可预知的( 具体化) , 坦率地说并不重要 。

您可以用堆叠做一些有趣的事情。 例如, 您的函数像单花(假设你能够通过有关其使用的大量警告) 这是一种专门用堆叠而不是堆叠来记忆的 中转器形式。

也就是说, 堆叠式的记忆错误是我经历过的最糟糕的记忆错误。 如果您使用堆积式内存, 并超越了分配区块的界限, 您就有一个很好的机会触发断段断层断层。 ( 不是100%: 您的区块可能附带地与先前分配的区块毗连 。 ) 但是由于堆叠上创建的变量总是相互连结, 边框中的写法可以改变另一个变量的值。 我了解到, 只要我感到我的程序不再遵守逻辑法则, 它可能就是缓冲溢出 。