不允许返回局部对象的引用?解决方案

不允许返回局部对象的引用?
#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);
}

------解决方案--------------------
然后你就被老板踹了
------解决方案--------------------
探讨

引用:

不能返回的。。。。无论局部的指针还是引用
局部指针的话,通常人都认为指向的局部变量失效,那该地址存的是垃圾值,其实不然,系统要在接到你要操作这个内存的指令后才会把它清0,它并不是立刻清0,就好比文件一样,并不是接到指令立刻把文件全清0,只是标记告诉系统这个空间可用,文件一般是在的。
数组也是一样,下面有个小实例,第一个能正常输入,第二个则不……

------解决方案--------------------
探讨
嗯嗯 有道理有道理
但是 你说的对于int& fun()这种函数,你能用int &a=fun();来接吗?显然是没有意思的,还是int a=fun();好

------解决方案--------------------
因为你用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();正是在退出函数时马上把栈里的值复制给别的变量了,所以不容易出错。