关于函数返回局部变量,最好能结合底层实现来回答
今天想搞清楚一个问题,写了两个小代码:(1)#include<stdio.h>
int main()
{
int *test()
{
int a = 2121;
int *p;
p = &a;
return p;
}
int *d = test();
int i = *d;
printf("%d",i);
return 0;
}
返回一个指向局部变量的指针,通过编译了。。。。
还能运行
然后(2)
#include<stdio.h>
int main()
{
int *test()
{
int a = 2121;
return &a;
}
int *d = test();
int i = *d;
printf("%d",i);
return 0;
}
返回一个局部变量的地址,并不能通过编译。。。。
那么问题来了,这是问什么呢? 本帖最后由 muyu0096 于 2016-4-4 01:44 编辑
首先,vs2010可以都可以运行,但都有同样的警告:试图返回局部变量的地址。
我推测你那里一个能运行一个不行,其实也是同样的原因。
关于动态变量a,其生命周期仅限于其函数块内,换句话说,出了函数块,这个变量对编译器来说就不存在了,因为编译器认为这块内存被释放了,虽然可能2121这个值还存放在这块内存上,但也可能随时被别语句所改变,所以是极容易出错的。而且更重要的是,不存在这个变量了, 你引用它的地址是没有意义的。
至于具体是否能通过编译还是仅仅是警告,那看编译器了。
至于你的第二个版本,估计你的编译器直接禁止编译通过了。
而第一个版本,你这里耍了一个花招,你把这个局部变量的地址赋给了一个指针,对于你的编译器,它会在返回的时候,创建一个临时变量,其值就是p的值,完成给d的赋值任务后,临时变量被销毁。就如同int fun(int b){return b+5;}一样的返回机制--通过临时变量返回一个值。形象的说,你的编译器笨点,它认为它通过临时变量返回了一个变量(p)的值,没有意识到这个p的值同样是一个临时变量的地址。
至于我的编译器,它识别出了这个花招,这从两个版本的汇编代码是一样的可以看出,但它认为不管怎么说,符合语言规范就行了,至于会出问题是你自己的事情,它聪明,但要求不那么严格。
本帖最后由 muyu0096 于 2016-4-4 01:57 编辑
本楼(不是2楼)写错了,无法删帖,只能这样。 muyu0096 发表于 2016-4-4 01:37
首先,vs2010可以都可以运行,但都有同样的警告:试图返回局部变量的地址。
我推测你那里一个能运行一个不 ...
原来这两个版本的汇编代码都是一样的,只是编译器看不出这里面可能存在问题,知道了,谢谢 love1577990779 发表于 2016-4-4 10:42
原来这两个版本的汇编代码都是一样的,只是编译器看不出这里面可能存在问题,知道了,谢谢
你的编译器两个汇编代码估计是不一样的,你调试一下就知道了。
页:
[1]