变量如何存储在堆栈中?

Posted

技术标签:

【中文标题】变量如何存储在堆栈中?【英文标题】:how variables are stored on stack? 【发布时间】:2015-03-09 05:02:12 【问题描述】:

我读到有两个内存区域,一个是堆栈,另一个是堆。 int、double、float 等基本数据类型存储在堆栈中,而引用类型存储在堆中。我们知道堆栈是LIFO,这意味着最后一个被推送的元素将首先被删除。现在假设以下代码

int first = 10;
double second = 20.0;
float third = 3.0F;

所以,first 将首先被推送,然后是 second,然后是 third。所以浮点类型的变量third 将位于堆栈顶部,但如果我使用以下代码(假设在 C# 中)

Console.WriteLine(second);

当变量third在栈顶时,如何访问变量second的值?

【问题讨论】:

您将一些非常低级的概念与一种高级语言混合在一起,为您抽象了所有这些概念。 表示变量存放的栈和数据结构中的栈不是同一个栈? 【参考方案1】:

您误解了the stack 的实际含义。有一个数据结构Stack 使用pushpop 来存储数据,但是基于堆栈和基于头的内存是一个更抽象的概念。您可以尝试查看基于堆栈的内存分配的Wiki article,但您还需要了解更多关于程序集和帧指针的信息。有关于这个主题的完整课程。

【讨论】:

【参考方案2】:

堆栈的行为与 PUSH 和 POP insturctions 的 LIFO 一样。但这并不意味着没有 pop 你可以读取堆栈内存。 在你的情况下 你

        push int first            (* its not a opcode of machine, just trying to explain)
        push  double second
        push float third 

        Now you have 2 options to access the variables that you have pushed.

       1) pop -> This is the one that reads and makes stack look like lifo.
         if you pop it
             stack will be
                    int first
                    double second.
            Bsically it removes(not exactly,just a register is chaged to show the stacks last valid memory position)

      2) But if you want you can jst read it without pop.Thus not removing the last times.
         So you will say Read me  double.And it will access the same way it does in heaps..
                  That will cause machine to execute  a mov instruction .

             Please note its EBP(Base pointer) and ESP(Stack pointer) that points to the location of a stacks variables.And machines read variables   as  mov eax,[ebp+2(distance of "second" from where base pointer is now pointing]].

【讨论】:

【参考方案3】:

我认为您误解了这个概念。

Eric Lippert 有几篇关于该主题的帖子,我建议您阅读。内存管理是一个高级主题。

The Stack Is An Implementation Detail, Part One The Stack Is An Implementation Detail, Part Two The Truth About Value Types

另外,found this great answer on what lives on the stack from Marc Gravell,复制如下。

“所有 VALUE 类型都将分配给 Stack”是非常非常错误的; 结构变量可以作为方法变量存在于堆栈中。然而, 类型上的字段与该类型一起存在。如果字段的声明类型是 类,值作为该对象的一部分在堆上。如果一个字段的 声明类型是一个结构,字段是该结构的一部分 该结构存在于何处。

即使是方法变量也可以在堆上,如果它们被捕获的话 (lambda/anon-method),或(例如)迭代器块的一部分。

【讨论】:

以上是关于变量如何存储在堆栈中?的主要内容,如果未能解决你的问题,请参考以下文章

参数变量存储在内存中的啥位置?

堆栈上的 C++ 实例变量存储为指针

C/C++程序中全局变量局部变量堆栈的存储区域介绍

C++ 中的全局变量是存储在堆栈、堆还是两者都不存储?

.NET - 存储在地址空间中的堆或堆栈上的函数变量?

iOS--------对堆栈 存储空间的理解