【问题标题】:Why stack and heap are so much separated in memory?为什么堆栈和堆在内存中如此分离?
【发布时间】:2020-10-17 14:02:29
【问题描述】:

我正在学习 c++ 并执行此代码

#include<stdio>
using namespace std;

int main(){

    char* buffer = new char[5];
    printf("%p", &buffer);                // 000000000061fe10
    cout<<endl;
    printf("%p", buffer);                  // 0000000000796b700
}

给了我 2 个完全分开的内存位置,我的意思是大约 150 万字节,那么为什么堆大小应该是 5 个字节呢? char size * 5. 堆向下增长(从 0xFFF ... 到 0x0000 ..)在堆下有堆栈,所以差异应该要小得多,所以在这种情况下内存布局是什么。以及我在上面的解释中没有完全理解的是什么

【问题讨论】:

  • 它们相差 120,895,728 字节,而不是 150 万字节。
  • “堆向下增长(从 0xFFF... 到 0x0000..)在堆下面有栈” 嗯?
  • 请注意,这种分离不一定是物理的,因为基本上所有主要操作系统都有虚拟内存。
  • 请注意,使用虚拟内存和地址转换,使用相距很远的两个内存区域基本上是免费的。见stackoverflow.com/questions/14347206/…
  • 堆增长和堆增长是我们教给学生的简化概念(它可能也是非常旧的计算机使用的)。这种简化可以很好地解释这个概念,但实际上它更多地取决于操作系统。我的意思是,如果您愿意,您可以在堆内实现堆栈(堆栈只是堆栈帧的链接列表,它们不需要物理上连续(尽管这是一个非常简单的实现)。

标签: c++ stack heap-memory


【解决方案1】:

内存的布局取决于操作系统、通常随操作系统提供的程序加载器、有关可执行文件的规则以及对链接器的请求。您尚未指定您使用的操作系统,因此无法给出明确的答案。

但是,内存地址是任意的。如果工匠布置他们的工具、说明、零件和工作空间,他们可以以任何他们想要的方式布置它们。没有要求堆栈靠近堆。很可能,堆被赋予了一个高地址,以便在虚拟内存空间中有足够的空间让它向下增长,或者它下面的东西向上增长的空间。由于虚拟内存是由从虚拟地址到物理地址的任意映射创建的,因此它的布局几乎没有限制——程序可以在这里使用几个地址,在另一个地方使用几个地址,在另一个地方使用几个地址,并且它可以在它们之间留下大量未使用的空间,并且未使用的空间不会消耗任何内存,因为它没有映射到物理内存。因此,虚拟内存的布局是在布局的人觉得方便的时候布局的。

【讨论】:

  • 我不认为我在这里关注所以这些输出是虚拟内存还是物理内存,这是否只发生在堆上我的意思是只有堆变量可以分散或堆栈变量也可以像这个例子一样分散
  • 作为用户模式程序,您永远不会看到物理地址。您的应用程序有数千 TB 的虚拟地址空间来放置东西,因此堆和堆栈理论上可以在其中的任何位置。也就是说,堆栈是连续的,因此一旦您看到其中的一个变量,相对而言,同一堆栈上的其他变量就会在附近。
  • 虚拟内存是对物理内存和可能多种不同类型物理内存的抽象。您的部分硬盘驱动器可以映射到虚拟内存。如果我们能弄清楚如何做到这一点,虚拟内存就可以映射到十亿个仓鼠轮子旋转中编码的数据
  • @MikeVine 非常感谢,但不同的堆栈没有这样的角色,它们就像这个领域的堆
  • @ahmedamr 对于大多数事情,您可以将内存地址视为标签。它们是数字,但如果它们被标记为名称,例如 foo 和 bar,则不会有太大区别。
猜你喜欢
  • 2012-05-16
  • 2019-12-07
  • 1970-01-01
  • 2011-10-09
  • 2012-12-05
  • 2019-05-17
  • 2012-11-02
  • 2019-10-23
  • 2020-04-25
相关资源
最近更新 更多