不允许返回局部对象的引用?解决方案
不允许返回局部对象的引用?
#include <stdio.h>
int& fun()
{
int i=100;
return i;
}
void main()
{
int a=fun();
printf("%d\n",a);
}
不允许返回局部对象的引用,为什么这里还是能正常输出100?
------解决方案--------------------
不能返回的。。。。无论局部的指针还是引用
局部指针的话,通常人都认为指向的局部变量失效,那该地址存的是垃圾值,其实不然,系统要在接到你要操作这个内存的指令后才会把它清0,它并不是立刻清0,就好比文件一样,并不是接到指令立刻把文件全清0,只是标记告诉系统这个空间可用,文件一般是在的。
数组也是一样,下面有个小实例,第一个能正常输入,第二个则不行,因为在它之前操作了这块内存,操作了这块内存。
#include <stdio.h>
int& fun()
{
int i=100;
return i;
}
void main()
{
int a=fun();
printf("%d\n",a);
}
不允许返回局部对象的引用,为什么这里还是能正常输出100?
------解决方案--------------------
不能返回的。。。。无论局部的指针还是引用
局部指针的话,通常人都认为指向的局部变量失效,那该地址存的是垃圾值,其实不然,系统要在接到你要操作这个内存的指令后才会把它清0,它并不是立刻清0,就好比文件一样,并不是接到指令立刻把文件全清0,只是标记告诉系统这个空间可用,文件一般是在的。
数组也是一样,下面有个小实例,第一个能正常输入,第二个则不行,因为在它之前操作了这块内存,操作了这块内存。
- C/C++ code
#include "stdafx.h" char * Cstr(void) { char a[10] = "like"; return a; } int main(void) { char *a=Cstr(); printf("%c\n",*(a+1)); printf("%c\n",*(a+1)); return 0; }
------解决方案--------------------
- C/C++ code
#include <stdio.h> int& fun() { int i=100; return i; } void main() { int a=fun(); printf("%d\n",a+1); printf("%d\n",a); }
------解决方案--------------------
然后你就被老板踹了
------解决方案--------------------
------解决方案--------------------
------解决方案--------------------
因为你用int接收,函数返回的int&马上被值拷贝到a,所以出错的概率非常小。
能想到的比较典型的出错情况是,进入fun时栈刚好跨页,从fun返回而还没有对a赋值时那个页面被置换,这时候再给a赋值会得到错误的值或者也可能非法访问。
------解决方案--------------------
- C/C++ code
#include <stdio.h> int& fun()//返回引用 { int i;//不初始化 return i; } int* fun1()//返回局部对象的内存地址 { int i = 1;//初始化 return &i; } int& fun2()//返回引用 { int i=100;//初始化 return i; } void main() { printf("%d\n",fun2());//输出返回引用的值 printf("%d\n",&(fun2()));//输出引用的局部对象的地址 printf("%d\n",fun1());//输出局部对象内存地址 printf("%d\n",*fun1());//输出局部对象的值 printf("%d\n",fun());//输出返回引用的值 printf("%d\n",&(fun()));//输出引用的局部对象的地址 //这种情况下你会发现他们用的是同一块内存,因为地址输出一致。也就是说栈内存是 //公共的区域,谁都可以写东西.你怎么保证引用后它的值就不会再变?也就是说在某个 //程序点也就是 a = fun2();这个函数调用结束后,还没有来得及把值赋给a,就在这个 //时间点上,存在某个程序代码对这个变量做了修改(比如多线程),那么把引用值赋给 //a的值我想不会再是函数返回的那么值100了! }
------解决方案--------------------
其实这个问题的重点是局部对象往往是分配在栈上的,随着函数调用,栈的内容会不断变化。
56楼,new出的对象是放在堆里的,而且是显式地为它分配了内存。
而函数中局部变量在退出时就释放了。
可以用汇编来解释。比如函数进入时堆栈寄存器sp=100,然后局部变量会是99、98……(栈是向下分配的),然后退出函数时,内存释放,sp会重置为100。
这个时候局部变量的值还在,但是之后随着新的局部变量或者调用函数要压栈什么的,sp就再次99、98……导致局部变量的值可能被覆盖。
int a=fun();正是在退出函数时马上把栈里的值复制给别的变量了,所以不容易出错。