函数返回类型是“引用”、“数值”和“指针”堆栈的变化

函数返回类型是“引用”、“数值”和“指针”的区别

一:背景

看到书中讲引用时候说:

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 






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值