【问题标题】:how stack memory can be used?如何使用堆栈内存?
【发布时间】:2017-12-21 13:16:50
【问题描述】:

在堆栈中,内存可以以 LIFO 方式存储,然后 我将向你展示一个例子来清楚地解释我的问题

public static void main()
{
  int i=0;
  char ch='a';
  string s="doubt";
}

在上面的示例中,第一个堆栈存储“i”值,在堆栈顶部存储“ch”值,在该堆栈顶部存储“s”值。现在的问题是,如果我想使用 'i' 值,它怎么能弹出来。如果弹出所有变量得到int'i'值,'s'和'ch'值在哪里,可以存储

【问题讨论】:

  • 欢迎来到 SO。您缺少语言标签(如果您想到 Java,请添加 java 标签)。所以请编辑你的问题来改进它(至少,为一些特定的编程语言添加适当的标签)。另请阅读call stack...
  • 好的,谢谢你 Basile Starynkevitch

标签: c# memory-management stack


【解决方案1】:

在上面的示例中,第一个堆栈存储“i”值,在该堆栈顶部存储“ch”值,在该顶部存储“s”值。

正确。请注意,您没有说“push”,这是不正确的。

现在的问题是,如果我想使用 'i' 值,如何将其弹出。

它不是“弹出”。它是通过当前堆栈帧基中的索引访问的。

如果 if 弹出所有变量以获得 int 'i' 值

没有。

's' 和 'ch' 值可以存储在哪里

在堆栈上,或者更好的是在当前堆栈帧中。

您应该将堆栈视为堆栈的堆栈,每个方法调用一个,而不是值堆栈。

【讨论】:

  • 好吧,这是一个很好的解释,但我对此有点困惑,我的困惑是“如果直接访问这些值,为什么所有人都说堆栈内存以堆栈格式存储数据,如 LIFO? "
  • 因为,正如我在回答中已经仔细解释过的,它是堆栈 frames 的堆栈。
【解决方案2】:

Java 实现通常将源代码编译为一些JVM 字节码。 C# 实现编译为CLI,即CLR 字节码称为CIL

JVM bytecode 用于基于堆栈的机器。 CIL 字节码也是stack-based。因此 JVM 和 CIL 字节码都针对一些 stack machine(但对于 Java -i.e.JVM- 和 C# -i.e. CIL- 是不同的)。

编译器将计算局部变量集并生成适当的指令来处理call stack中的当前帧。

从概念上讲,当控制流退出声明它的block 时,会弹出局部变量的槽(在当前调用帧中)(但实际上发生的是实现细节)。阅读scope。所以你不需要显式地弹出任何值(编译器负责嵌套范围和局部变量)。

很多时候,调用框架在function prologue 中的调用期间被推送(在调用堆栈上),并在(相应的)函数尾声中被弹出(从调用堆栈中),但细节取决于calling conventions .

JVM 需要garbage collector,CIL 也是如此。它会扫描堆栈上的指针(指向对象)(在您的示例中为s

顺便说一句,Java 有一些reflection 设施(不适合新手),可以访问调用堆栈。见this。 C#(和 CIL)也提供了reflection。另请阅读continuations

调用堆栈确实是遵循last-in first-out 规则的stack,但拉取和弹出操作是调用协议的一部分,并且是编译器生成的,因此保持隐式。在调用期间,一个新的调用帧被压入调用堆栈。返回时,它会从调用堆栈中弹出。另请阅读tail-calls(然后在调用时新调用框架替换当前调用框架);遗憾的是,JVM 通常不支持尾调用。

我建议阅读SICP,其中有一些章节解释了这些概念。这是一本很好的免费编程介绍(使用 Java 或 C# 作为其编程语言)。

【讨论】:

  • 您可能想提一下,在函数内部,可以直接访问局部变量(通过堆栈框架)-IMO 这就是 OP 所困惑的(“如果我想使用 'i ' 值如何弹出")。请参阅@EJPs 答案(“它通过索引访问”)
  • @AndreasFester:当然可以直接访问局部变量(例如,在 OP 的示例中进一步引用 i
  • 完全正确-您部分提到了它(“不需要显式弹出”)-只是认为可以更清楚地提及它们仍然可以直接访问(意味着,不仅像在“纯”堆栈中那样通过推送/弹出)。在 OP 的示例中,“s”和“ch”仍然存在,在同一位置,但“i”只是直接访问
  • 谢谢你这是一个很好的解释,我怀疑它是否直接访问,那么为什么他们说堆栈内存遵循 LIFO 方式。你能回答我的疑问吗!
猜你喜欢
  • 2010-10-27
  • 2011-03-13
  • 2021-09-22
  • 2014-10-13
  • 2011-08-15
  • 1970-01-01
  • 1970-01-01
  • 2017-02-08
  • 2012-06-03
相关资源
最近更新 更多