堆栈上变量的位置没有使用(&)

时间:2011-02-28 11:33:09

标签: c++ c stack memory-management

我正在尝试确定一种测试堆栈变量位置的方法(不用常识方式)。

   int main()
    {
      int i,j;
      return 0;
    }

说明int i之间真的没有区别; INTJ;和int i,j;我只能简单地告诉地址。我进入堆栈,然后j进入堆栈。但无论如何,我可以使用内存地址运算符(或指针)告诉这个。

这是一项具体的任务。可能这样我就可以理解堆栈以这种方式实现的原因。我可以很容易地确定它们是如何定位的(是的,它是编译器特定的,但是为简单起见而gcc)。

所以是的,我的意思是在这里艰难地做事......弄清楚并说明为什么以及如何以特定的方式实现堆栈

我可以添加更多代码,更多函数..无论如何..但重点是在没有&

的情况下演示堆栈的排序

5 个答案:

答案 0 :(得分:4)

因此,您希望找到局部变量的地址,而无需使用专门设计的C运算符来查找变量的地址。为什么呢?

值得指出的是,在任何现代编译器/处理器组合中,如果不使用&运算符,示例中的i和j可能不在堆栈中。即使你对它们做了一些事情,所以编译器也没有对它们进行优化,它仍然可以选择将它们放在寄存器中。


编辑:我已经阅读了您对datenwolf答案的评论,我想我知道您的要求是什么。这是一个可能的答案,但我必须强调,我正在对你的编译器做出很大的假设。特别是,

  • 所有变量都存储在堆栈中
  • 变量未被优化掉(关闭编译器中的所有优化)。
  • 自动数组的存储空间直接在堆栈上分配
  • 在函数调用之间未清除堆栈

如果你有这样的功能:

int f()
{
    int i = 1, j = 2;
    return 0;
}

您可以使用此功能检查内存中i,j的顺序:

void order()
{
    int a[2];
    if (a[0] == 1)
    {
        printf("i first\n");
    }
    else
    {
        printf("j first\n");
    }
}

int main()
{
    f();
    order();
    return 0;
}

切勿在实际代码中使用上述内容。它依赖于几种官方未定义的行为。

答案 1 :(得分:3)

不,您应该使用&运算符来获取变量的地址。

答案 2 :(得分:3)

AFAIK无法保证C和C ++标准中的排序。即,当您可能检测不到任何差异时,使用不同的编译器或不同(优化)设置时可能会有所不同。 (事实上​​,优化器也可能重新排序i和j或完全删除它们)

所以是的,你需要使用“地址”。你为什么不呢?

答案 3 :(得分:2)

你为什么要这样做? i和j在堆栈上的位置取决于实现。事实上,在许多实现中,i和j不会占用示例中的任何位置,因为它们从未被使用过。确定的唯一方法是查看生成的代码(如果使用变量的地址,则会有所不同)。

答案 4 :(得分:1)

语言C甚至没有称为堆栈的概念。它只定义了自动存储的行为,大多数编译器使用大多数体系结构提供的堆栈来实现它。

即使&运算符纯粹是抽象的,并且它返回的值,在其数值表示中可以是任何东西,只要它遵循指针运算的规则。但是这个数字,它可能完全是虚拟的,与指令中使用的地址完全无关。

因此,虽然确定变量是否位于堆栈上的任务已经明确定义,但根据定义,使用纯ANSI C无法实现,而不依赖于特定于实现的行为。执行此任务的常用方法是执行堆栈遍历,由实现运行时库的函数提供。

很抱歉,我不能比这更具体。与它作为一种非常低级语言的声誉不同,C实际上是用非常抽象的术语定义的,并且C程序中发现的许多编程错误源于这种误解。