原始代码是:
int main(){
int sam= 19;
int *pSam= &sam;
printf("Address \t name \t value\n");
printf("%p \t %s \t %d\n", pSam, "sam", sam);
return 0;
sam的内存地址显示为= 0028FF18。
但是,如果我对变量一无所知,只需在'return 0;'上方添加另一行代码。这是:
printf("%p \t %s \t %p", &pSam, "sam", pSam);
然后运行程序,sam的内存地址变为0028FF1C,即使我刚刚打印出一些基本内容。
为什么?
答案 0 :(得分:0)
正如评论中所提到的,这几乎肯定是关于优化的。
此:
int main() {
int sam = 19;
int *pSam = &sam;
printf("Address \t name \t value\n");
printf("%p \t %s \t %d\n", pSam, "sam", sam);
return 0;
}
基本上等同于:
int main() {
int sam = 19;
/* int *pSam = &sam; */
printf("Address \t name \t value\n");
/* printf("%p \t %s \t %d\n", pSam, "sam", sam); */
printf("%p \t %s \t %d\n", &sam, "sam", sam);
return 0;
}
换句话说,它可以在没有变量pSam
的情况下完成,因此,智能编译器将优化该变量。根据处理器的不同,即使没有对其进行优化,它也可以将所有内容存储在寄存器中,而不是在堆栈上分配存储空间。
但是,如果你想取pSam
的地址,那么很明显它不能被优化掉或放入寄存器中,因为如果你做其中任何一项,那么它&# 39;不会有地址。因此,当你这样做时,你强制编译器为它分配内存,几乎可以肯定是在堆栈上。并且,在这种情况下,看起来当你这样做时sam
的地址 - 也必须在堆栈上分配,因为你也取其地址并输出它 - 结果正在改变,可能是因为你的编译器在pSam
之前在堆栈上分配sam
。
答案 1 :(得分:0)
虽然不是那么明显,可能导致这是一个无效的编译器优化。
在原始代码中
int main() {
int sam = 19;
int *pSam= &sam;
printf("Address \t name \t value\n");
printf("%p \t %s \t %d\n", pSam, "sam", sam);
return 0;
}
您可能会注意到pSam
变量的地址从不需要,因此编译器可以完美地优化该变量,从而导致更小(几个字节......)堆叠。
现在,当您在混音中添加另一行时。
printf("%p \t %s \t %p", &pSam, "sam", pSam);
编译器优化失效,也就是说,它的断言(永远不会使用pSam
的地址)不再有效,因此优化不可用。这意味着变量pSam
现在没有被优化掉,现在实际上存在于堆栈空间中,从而推动,移动或以其他方式修改过程中其他堆栈变量的地址。