【问题标题】:Variable declared interchangebly has the same pattern of memory address可互换声明的变量具有相同的内存地址模式
【发布时间】:2013-11-25 03:22:01
【问题描述】:

我有一个函数,在函数中,我有两个变量,

  int auth_flag = 0;
  char buffer[16];

现在这里是gdb命令x/s buffer的输出

0xffffd01c: "\201\203\004\b\344\203\373\367\002"

print &auth_flag的输出

$1 = (int *) 0xffffd018

现在,我们从输出中看到,auth_flag 的位置是缓冲区之前的 4 个字节。现在,如果我这样声明变量

char buffer[16];
int auth_flag = 0;

前面命令的输出是

0xffffd00c: "\201\203\004\b\344\203\373\367\002" and
$1 = (int *) 0xffffd008

同样的事情。落后 100 个字节,但顺序相同。我的问题是,由于我已经反转了变量声明,为什么在 gcc 中变量的地址顺序没有反转。我正在读一本书,据说地址应该颠倒,但这并没有发生在我的电脑上。所以我真的很困惑。

【问题讨论】:

  • 强制不优化可能吗? #pragma OPTIMIZE OFF
  • @Leonardo:一个非常糟糕的想法。即使它在这种情况下有效,它也具有很大的误导性,因为该语言不能保证编译器在哪里分配自动变量。

标签: c++ c gdb


【解决方案1】:

如果这本书说自动变量在标准 C 或 C++ 中彼此之间有任何特定的地址关系,那就把它烧掉。 structclass 中的字段具有实现定义的布局。自动变量甚至不能保证分配到内存。

现在,C++ 所做 保证的是定义符号的顺序(编译时构造,而不是内存布局问题),以及调用构造函数的顺序。例如,该顺序以精确的方式定义了以下代码的含义:

int foo(int x)
{
    int y = x;  // this sees the argument x
    int x = 3;  // this defines an automatic variable named x that shadows the argument

    return x + y;
}

C++ 还保证了对象的构造和销毁顺序。 (当它们按出现顺序进入作用域时被构造,在它们离开作用域时以相反的构造顺序被破坏。)但是,我不会深入研究,因为这超出了你的问题。

【讨论】:

  • 这个变量在一个函数中。
  • 函数的局部变量是自动变量。它们通常(但不总是)分配在堆栈上。该语言做出的唯一保证是,当它们进入范围时它会自动为您分配它们,并在它们超出范围时自动为您删除它们。
  • 从你的变量名来看,你不会碰巧在练习写缓冲区溢出吧? ;-)
  • 那么,函数的栈是如何定义的呢?如果不保证分配自动变量,那么当函数被压入堆栈时会发生什么,那么应该为变量分配内存。它们按什么顺序分配?
  • 是的,就是这样。我正在练习 buffer_overflow :D
猜你喜欢
  • 2013-05-10
  • 2023-03-03
  • 2018-06-04
  • 2014-04-24
  • 1970-01-01
  • 1970-01-01
  • 2014-04-30
  • 2016-03-17
  • 2022-01-11
相关资源
最近更新 更多