变量在堆栈上的存储方式

本文关键字:存储 方式 堆栈 变量 | 更新日期: 2023-09-27 18:37:01

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

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

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

Console.WriteLine(second);

当变量third位于堆栈顶部时,如何访问变量second的值?

变量在堆栈上的存储方式

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

我想你误解了这个概念。

Eric Lippert's有几篇关于这个主题的文章,我推荐阅读。内存管理是一个高级主题。

  • 堆栈是实现细节,第一部分
  • 堆栈是实现细节,第二部分
  • 关于值类型的真相

另外,从Marc Gravell那里找到了关于堆栈上的内容的这个很好的答案,复制在下面。

"所有值类型都将分配给堆栈"是非常非常错误的;结构变量可以作为方法变量存在于堆栈上。然而类型上的字段与该类型一起存在。如果字段的声明类型为类,这些值作为该对象的一部分位于堆上。如果字段声明类型是结构,字段是该结构的一部分无论结构在哪里生活。

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

堆栈的行为就像带有 PUSH 和 POP 的 LIFO。但这并不意味着没有弹出就可以读取堆栈内存。在您的情况下 你

        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]].