如果将变量分配到堆栈中,如何随时检索变量?

时间:2012-09-05 16:35:35

标签: memory-management callstack

据我所知,每个线程通常只获得一个堆栈(而进程中的所有线程通常共享一个堆)。我一直认为堆栈用于在函数调用发生时存储程序计数器(PC)的值。但后来我在某处读到某些变量类型,例如integerboolean也被分配到堆栈中。由于堆栈上的值是以严格的FILO方式管理的,因此如何随时检索这些变量?

例如,在声明int a, b, c;之后,我可以在其范围内的任何时间以任何顺序对这些变量执行任何操作。这是怎么做到的?为什么值c不在堆栈顶部,因此隐藏值a, b

3 个答案:

答案 0 :(得分:1)

调用堆栈也用于局部变量,也用于将参数传递给函数。

你是正确的,'值类型'在堆栈上传递,而引用类型在堆上分配,但是当引用类型用作参数时,指向此堆位置的指针仍将传递给叠加。

虽然堆栈通常被“感知”为LIFO缓冲区,但也有与调用堆栈关联的帧或基指针,可用于直接访问当前堆栈指针上方或下方的内存。这就是函数如何在不改变堆栈指针的情况下随机访问参数。

这个diagram from Wikipedia可能有助于形象化,但请注意许多人会认为堆栈应该“向下”增长。

此博文here解释了英特尔调用堆栈

答案 1 :(得分:1)

首先,我建议您应该更多地研究堆栈(请参阅WikipediaStack Explanation以及其他人通过Google搜索/ CS书籍)。

但是对于您的特定问题,所有未生成堆的变量都在堆栈中。这通常包括您在特定函数中定义的任何内容,这些函数不是直接堆分配的(通过C ++和Java中的new运算符)。在某些语言中,所有内容都是堆分配的,只有指向这些堆结构的指针存储在堆栈中(就像在Python中一样)。你会在语言之间看到各种微小的变化。

因此,关于整数和布尔值的语句总是在堆栈上是不正确的。如果您在函数内定义它们,并且如果使用new构建它们,则它们位于堆栈中。请注意,对于Java,如果使用int原语,它通常是基于堆的,Integer对象是基于堆的 - 但这是Java的基本堆栈知识之外的更高级的细微差别。

您可以在同一范围内访问int a, b, c;,因为它为该功能堆栈范围内的所有3个变量腾出空间。当函数返回时,这些变量会在堆栈向上移动时被清除。在此之前所有3都存在,因为整个范围块一次是堆栈的FILO结构的一部分,并且将一直存在直到你返回。

答案 2 :(得分:1)

根据您正在使用的环境,该问题有很多答案。当然,您不应将处理器堆栈与(与机器代码POP和PUSH一起使用)指令等同于堆栈(或更正确的堆栈框架) )使用python解释器或.net运行时

之类的东西

但简短的回答是堆栈的顶部只是一个内存位置,所以你只需使用偏移量

如果你做了推a,b,c

所以b的地址是堆栈地址--4。