我试图理解C中的堆栈帧,所以我写了一个简单的C代码来分析堆栈帧。
首先,fun1()返回一个局部变量的地址,该地址变量初始化为10到ptr,这会导致警告,但是没问题......如果我打印* ptr的值现在它打印10,即使那很好......
接下来fun2()返回一个甚至没有初始化的局部变量的地址,如果我尝试打印* ptr的值,无论我是否返回一个地址,它都会打印10或者b ...
为了理解这里发生了什么,我使用了gdb。 使用gdb,我开始逐步调试,当我到达线路时,返回& a "在fun2()中,我尝试打印b的地址, print& b 但是它打印出来了 无法获取" b"的地址这不是一个左值。
我不明白,当我尝试打印a,打印& a 的地址时,它打印得非常好,为什么不打印b的地址。 *当a为什么时,为什么不是左值?
# include <stdio.h>
int * fun1() {
int a = 10;
return &a;
}
int * fun2()
{
int a;
int b;
return &a; // return &b;
}
int main ()
{
int *ptr;
ptr = fun1();
ptr = fun2();
printf ("*ptr = %d, fun2() called...\n", *ptr);
return 0;
}
答案 0 :(得分:3)
编译器正在优化fun2
中的一些代码。
如果您返回&a
,则会优化int b;
。如果您返回&b
,则会优化int a;
。如果添加一些虚拟计算,您将看到返回值的地址不同。
int * fun2()
{
int a;
int b;
int* p = &a;
p = &b;
return p;
}
更改main
以打印fun1
和fun2
的返回值。
int main ()
{
int *ptr;
ptr = fun1();
printf ("ptr = %p, fun1() called...\n", ptr);
ptr = fun2();
printf ("ptr = %p, fun2() called...\n", ptr);
printf ("*ptr = %d, fun2() called...\n", *ptr);
return 0;
}
当我运行此代码时,我得到以下示例输出:
ptr = 0x7ffff98c70ec, fun1() called... ptr = 0x7ffff98c70e4, fun2() called... *ptr = 32749, fun2() called...
答案 1 :(得分:0)
在将地址返回到b时,它为我编译就好了。但是你不应该返回局部变量的地址。 Check out this link