【问题标题】:why accessing an address of a variable changes the address of another variable?为什么访问一个变量的地址会改变另一个变量的地址?
【发布时间】:2012-12-07 21:15:54
【问题描述】:

代码 1:

int main(){
   int a=1;
   int b=2;
   cout << "&a: "<<&a << endl;
}

输出 1:

&a: 0x22ff48

代码 2:

int main(){
   int a=1;
   int b=2;
   cout << "&a: "<<&a << endl;
   cout << "&b: "<<&b << endl;
}

输出 2:

&a: 0x22ff4c
&b: 0x22ff48


所以我的问题是为什么当我打印出变量b 的地址时变量a 的地址发生了变化?

【问题讨论】:

    标签: c++ memory memory-address


    【解决方案1】:

    当你根本不使用b时,编译器可能会完全删除它,所以它不占用任何空间。

    当您获取b 的地址时,这会强制编译器为其分配空间。

    【讨论】:

    • 此外,它可能没有消除它,而是只将它分配给一个寄存器,因为它的地址从未被占用。
    • @DaveS:当然也可以。
    • @JerryCoffin 仅在我访问变量 b 的地址时才适用,因为如果我打印出变量 b,code1 中没有任何变化,就好像编译器在编译时用它的值替换 b 一样,并且b 根本没有被分配。
    • @AlexDan:请记住,我们在这里只处理概率。也就是说:是的,如果变量从不改变,大多数编译器都可以消除它。正如 DaveS 所指出的,如果他们的地址从未被占用,并且没有什么比占用寄存器更重要的,他们也可以将它们分配给寄存器。
    【解决方案2】:

    无论如何,下次操作系统可以在另一个(虚拟)基地址上加载可执行映像。

    你所观察到的是 undefined 无论如何。关键是,即使没有变量被优化掉,并且程序没有被重新编译,它每次都可能产生不同的结果。

    如果您将操作系统视为实现

    的一部分,它可能是实现定义的

    【讨论】:

    • 至少在典型的实现中,这里重要的不是可执行映像的加载地址,而是堆栈的基地址(当然,这也可能有所不同) .
    • 我将其称为“未指定”而不是“未定义”。 ;)
    • @Yakk 事实上,它未定义的。该标准没有指定它应该由实现定义。 (哎呀,标准甚至没有指定 &amp;a 应该代表一个 address (逻辑或物理)。它只是......一个“指针”,它是一种抽象。标准 确实在一些有限的情况下指定“指针”必须具有确定性可比性:stackoverflow.com/questions/9086372/how-to-compare-pointers/…)
    • 您是否声称int a=0;std::cout &lt;&lt; &amp;a; 可以在符合标准的编译器上出现段错误?我希望标准未指定您获得的值,但我怀疑将指针流出的行为是“未定义的行为”。
    • @Yakk 不,我没有这么说。结果将由实现定义。但是在“相同情况”(海森堡?)中相同代码的不同运行结果是否相同是未指定
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-20
    • 2021-12-18
    • 1970-01-01
    相关资源
    最近更新 更多