函数返回类型是“引用”、“数值”和“指针”的区别
一:背景
看到书中讲引用时候说:
int& f()
{
int i;
//...
//***** ERR:i goes out of existence
return i;
}
错误的原因是:当f()返回时,i就已经不存在了,因此不能访问。
之后自己写了个测试程序试了一下
typedef struct TEST_STRUCT
{
int a;
char b;
}test_s;
test_s& fun(int a,char b)
{
test_s t1;
t1.a = a;
printf("argm b ==>%c\n",b);
t1.b = b;
printf("t1.b ==>%c\n",t1.b);
return t1;
}
测试main()
test_s t2={0,0};
t2 = fun(1,'a');
printf("int=>%d\n",t2.a);
printf("char=>%c\n",t2.b);
cout<<"t2.b="<<t2.b<<endl;
t2.a = 777;
t2.b = 'z';
printf("int(Modifyed)=>%d\n",t2.a);
printf("char(Modifyed)=>%c\n",t2.b);
奇怪的是结果 int正常,而char显示“?” ,cout无显示
,两者都可以更改,截图如下:
这就奇怪了,如果释放掉了 为什么int能打印出来?可既然打印出来了 为什么char是“?”,cout都没反应呢
指针和结构体整体拷贝的方法 显示都是正确的(全都是vc 6的环境,别的环境没测)
二:解答
查了一下
http://topic.csdn.net/t/20051120/20/4406149.html
http://zhidao.baidu.com/question/156881190.html
这两个说的挺好
重点是:
首先局部变量在函数执行完后会被释放,这个毋庸置疑。
问题出在系统什么时候会释放被调用的函数栈数据。
如果在没有任何函数被调用时,原来的函数栈还是被保留的,直到调用了新的函数,新的函数栈冲掉了原来的函数栈。
因此,函数返回指针后,必须在下一个函数中立即取出,不然就被冲洗掉了。
在函数里面定义的普通对象如(int a)是在栈里分配内存的,在函数运行结束后就被释放了,不过如果是在函数里面指针是新生成的(如int* a = new int),是指针a是在堆里分配内存,函数运行结束后不会被释放,不过但是楼主在接到传回的指针后,要记得释放内存哦,要不然就会有内存泄漏了。
释放后那块内存并不是马上就被其他地方占用,根据实际情况起码会空闲一会,可能是一瞬间。如果你的程序较复杂,那这块内存可能很快就再次被使用,如果程序很简单,可能在很长一段时间内都是空闲。
所以在函数返回后将变量的值马上赋值给另外一个变量,局部变量已经销毁了,这块内存上的值还没来得及被修改,所以你的外部变量获得了一个正确的值。
所以你的结果正确并不代表变量没有被销毁。无论用引用还是变量来接受局部变量的值,局部变量肯定是已经销毁了的
测试代码:
double* big(double a,double b)
{
printf("&a = %x &b = %x\n", &a, &b);
double* c = ( (a > b) ? &a : & b);
printf("return %x \n", c);
return c;
}
double main()
{
double a = 3.9, b = 2.0;
printf("&a = %x &b = %x\n", &a, &b);
double* c = big(a,b);
double d = *c;
//printf("big = %x \n", c);
printf("%f %x \n", *c, c);
printf("%f %x \n", *c, c);
printf("%f %x \n", d, &d);
return 0;
}
测试结果如下: 立即取出返回值 &a = bfc99b60 &b = bfc99b58 &a = bfc99b20 &b = bfc99b18 return bfc99b20 3.900000 bfc99b20 0.000000 bfc99b20 3.900000 bfc99b50 执行一个函数后再取返回值: &a = bfb0b9d0 &b = bfb0b9c8 &a = bfb0b990 &b = bfb0b988 return bfb0b990 === 0.000000 bfb0b990 0.000000 bfb0b990 3.900000 bfb0b9c0