精华内容
下载资源
问答
  • 局部变量是存在于栈中的,函数被调用时先在栈中为变量申请空间,调用完成释放变量空间。函数在返回参数的时候是这样的,先把要返回的数放在寄存器eax中,然后回到主函数中取出eax中的数值放在变量里,所以这样是...
    局部变量是存在于栈中的,函数被调用时先在栈中为变量申请空间,调用完成释放变量空间。函数在返回参数的时候是这样的,先把要返回的数放在寄存器eax中,然后回到主函数中取出eax中的数值放在变量里,所以这样是不涉及函数中变量地址的。如果要返回引用,也就是变量地址,那么它会把这个变量的地址放在eax中,(注意这个地址是位于函数的栈空间里的,出了这个函数,这块内存就会被系统标记为可占用(就是其它程序可以占用)),回到主函数后系统会把这个地址赋值给主函数中的指针变量。此时主函数中的指针变量就指向了一个已经被标记为可占用的内存空间。如果你在不同的时刻输出这个指针所指地址的值会输出不同的结果。我的测试程序如下:
    #include <stdio.h>
    
    int * fun()
    {
     int p;
     p = 100;
     return &p;
    }
    int * fun2()
    {
     int p;
     p = 200;
     return &p;
    }
    void main()
    {
     int *p , *q;
     p = fun();
     printf("%d\n" , *p);
     q = fun2();
    
     printf("%d\n" , *p);
     return;
    }
    
    这个程序和缓冲区溢出攻击原理有点相似,
    另一种解说法方法
    返回值是数值时,是将函数中的局部变量里存的值赋给另一个变量
    例如a=fun(b,c);就是将fun函数里面的局部变量赋值给a,之后fun函数里的局部变量会释放,回收他们的内存空间,因此一旦出了fun函数,那么里面的局部变量就没有意义了。
    而返回引用的时候,引用的变量的内存空间不会因为函数结束而被回收,因此出了fun函数后,引用的变量仍会保持最后一次被改动的值。

    要么都不加,直接返回变量的副本 要么返回引用  此时局部变量声明为静态的 这两种情况都是对的,所以下面两种写法都是正确的:
    int add1(int a, int b) 

    int sum; 
    sum = a + b; 

    return sum; 


    int& add2(int a, int b) 

    static int sum; 
    sum = a + b; 

    return sum; 

    展开全文
  • 在编写c/c++代码时,调用函数的书写让程序变得整洁易读,但是调用函数的返回值(局部变量... 函数的返回值不能是局部对象或者是局部变量的指针或引用!!! 原因:  调用函数的局部变量是存在于栈中的,在执行完...

    在编写c/c++代码时,调用函数的书写让程序变得整洁易读,但是调用函数的返回值(局部变量的返回值,变量,结构体,数组等)也有注意事项。c/c++严禁返回局部变量的指针或引用。

    其实函数的返回值的规则非常好记:

      函数的返回值可以是数值和全局变量的指针或引用。

      函数的返回值不能是局部对象或者是局部变量的指针或引用!!!

    原因:

      调用函数的局部变量是存在于栈中的,在执行完调用函数之后会将局部变量的空间释放,也就是调用函数执行后局部变量将不存在与内存中。如果返回的是局部变量的指针或者是引用。返回给接收对象的是局部变量的地址,而这个地址的资源已经被释放了,也就是接受的返回值都将是空值(因为被释放),会出错。

     

    补充:局部变量返回指针或引用都是地址,而返回数值是值。(概念不同)

    转载于:https://www.cnblogs.com/spring-hailong/p/6135589.html

    展开全文
  • C++Primer第7章函数一节,讲到返回时,“理解返回引用至关重要的是,千万不能返回局部变量的引用”, 意思是返回程序内部定义的变量时可能会出问题,因为当函数执行完毕后,将释放分配给局部对象的存储空间。 此时,...

    C++ Primer第7章函数一节,讲到返回时,“理解返回引用至关重要的是,千万不能返回局部变量的引用”,

    意思是返回程序内部定义的变量时可能会出问题,因为当函数执行完毕后,将释放分配给局部对象的存储空间。

    此时,对局部对象的引用就会指向不确定的内存。
     

    展开全文
  • 最重要的一点:函数不能返回指向栈内存的指针! 为什么?因为返回的都是值拷贝!  一般的来说,函数是可以返回局部变量的。 局部变量的作用域只在函数内部,在函数返回后,局部变量的内存已经释放了。因此,如果...

    最重要的一点:函数不能返回指向栈内存的指针!

    为什么?因为返回的都是值拷贝!

            一般的来说,函数是可以返回局部变量的。 局部变量的作用域只在函数内部,在函数返回后,局部变量的内存已经释放了。因此,如果函数返回的是局部变量的值,不涉及地址,程序不会出错。但是如果返回的是局部变量的地址(指针)的话,程序运行后会出错。因为函数只是把指针复制后返回了,但是指针指向的内容已经被释放了,这样指针指向的内容就是不可预料的内容,调用就会出错。准确的来说,函数不能通过返回指向栈内存的指针(注意这里指的是栈,返回指向堆内存的指针是可以的)。

           我们知道,局部变量的作用域是函数内部,函数一旦执行结束,栈上的局部变量会进行销毁,内存得到释放。因此,此时函数返回的是该局部变量的值拷贝,这是没有问题的。但是如果返回的是局部变量的地址,那么返回的只是该局部变量指针的拷贝,而随着函数运行结束,该拷贝指针所指向的栈内存已经被释放,那么指向一个未知区域就会导致调用的错误。

          那如果返回的指针指向的是堆内存,又会怎么样?

          这样的使用是没有问题的,在函数内new空间,在函数外delete空间。但是这样并不是一种好的编程风格,尽量在同一个作用域内进行new和delete操作,否则还要调用者手动进行内存的释放,试问这样的接口是不是很烂。如果确实需要这样做,那就传指针进去吧!

    #include "fun_stdy.h"
    #include <iostream>
    using namespace std;
     
    int return_value0(){	
    	int ret = 0;
    	cout << " in return_value0 , address and value:"<< &ret <<" "<< ret <<endl;
     
    	return ret;		//ok 最常见的情况, 返回局部变量的副本
    }
     
    int* return_value1()  
    {  
    	int ret=1;  
    	cout << " in return_value1 ,  and value:"<< &ret<<" " << ret <<endl;
     
    	return &ret;	//error 虽然value被释放 , 但里面的值可能不会被清除,所以有时候你这么用
    					//看起来结果好像也是对的,但是隐患无穷。
    } 
     
    int* return_value2()  
    {  
    	int *ret = new int(2); 
    	cout << " in return_value2 , address and value:"<< &ret <<" " << ret <<endl;
     
    	return ret;  //ok 在函数内申请空间,调用后需要调用者手动在函数外释放空间
    } 
    int* return_value3(int *ret)		//指针value不能为null,否则报错
    {  
    	ret = new int(3);  
    	cout << " in return_value3 ,  address and value:"<< &ret<<" " << ret <<endl;
     
    	return ret;  //ok 在函数内申请空间,调用后需要调用者手动在函数外释放空间
    } 
     
    char *return_value4()
    {
    	char p[] = "hello world";
    	cout << " in return_value4 ,  address and value:"<< &p<<" " << p <<endl;
     
    	return p;    //p[]数组为函数内部局部变量,在函数返回后,内存已经被释放了,
    	//所以在主函数中调用该函数str2 = return_value3();输出的可能为乱码
    }
     
    //此函数中p也是个局部变量,函数执行完自动销毁,但是指针分配的空间不会被自动回收,除非程序员delete掉。
    //所以这个可以正常输出。
    char *return_value5()
    {
    	char *p = "hello world";//这个初始化的一种形式,相当于分配了sizeof(hello world)个空间
    	cout << " in return_value5 ,  address and value:"<< &p <<" "<< p << endl;
     
    	return p;
    }
     
    /*		如果真要返回局部变量的引用和指针 ,请用static		*/
     
    char *return_value6()
    {
    	static char p[] = "hello world";
    	cout << " in return_value6 , static_pointer's address and value:"<< &p <<" "<< p << endl;
     
    	return p;
    }
    
    
    #include <iostream>
    #include "fun_stdy.h"
    using namespace std;
     
    int main(int argc, char **argv){
    	int *p ,*q;
    	char *pchar;
     
    	cout << " in main ,return_value0() :" << return_value0()<< endl<< endl;
     
    	p = return_value1();
    	cout << " in main ,return_value1() :" << p<< "	" << *p << endl<< endl;
     
    	p = return_value2();
    	cout << " in main ,return_value2() :" << p<< "	" << *p << endl<< endl;
     
    	q = p;
    	cout << " before return_value3 , q: " << q << "	"  << *q <<endl<< endl;
    	p = return_value3(q);
    	cout << " in main ,return_value3() :" << p<< "	" << *p << endl<< endl;
    	cout << " after return_value3 , q: " << q << "	"  << *q <<endl<< endl;
     
    	pchar = return_value4();
    	cout << " in main ,return_value3() :" << pchar<< "	" << *pchar << endl<< endl;
     
     
    	pchar = return_value5();
    	cout << " in main ,return_value5() :" << pchar<< "	" << *pchar << endl<< endl;
     
     
    	pchar = return_value6();
    	cout << " in main ,return_value6() :" << pchar<< "	" << *pchar << endl<< endl;
     
    	system("pause");
    	return 0;
    }
    
    #include <stdio.h> 
    char *returnStr() 
    { 
        char *p="hello world!"; 
        return p; 
    } 
    int main() 
    { 
        char *str; 
        str=returnStr(); 
        printf("%s\n", str); 
        return 0; 
    }
    
    这个没有任何问题,因为"hello world!"是一个字符串常量,存放在只读数据段,
    把该字符串常量存放的只读数据段的首地址赋值给了指针,所以returnStr函数退出时,
    该该字符串常量所在内存不会被回收,故能够通过指针顺利无误的访问。
    #include <stdio.h> 
    char *returnStr() 
    { 
        char p[]="hello world!"; 
        return p; 
    } 
    int main() 
    { 
        char *str; 
        str=returnStr(); 
        printf("%s\n", str); 
        return 0; 
    } 
    
    "hello world!"是局部变量存放在栈中。当returnStr函数退出时,栈要清空,
    局部变量的内存也被清空了,所以这时的函数返回的是一个已被释放的内存地址,
    所以有可能打印出来的是乱码。 
    int func()
    {
          int a;
          ....
          return a;    //允许
    }                   
     
    int * func()
    {
          int a;
          ....
          return &a;    //无意义,不应该这样做
    } 
    
    局部变量也分局部自动变量和局部静态变量,由于a返回的是值,因此返回一个局部变量是可以的,无论自动还是静态,
    
    因为这时候返回的是这个局部变量的值,但不应该返回指向局部自动变量的指针,因为函数调用结束后该局部自动变量
    
    被抛弃,这个指针指向一个不再存在的对象,是无意义的。但可以返回指向局部静态变量的指针,因为静态变量的生存
    
    期从定义起到程序结束。
    

    如果函数的返回值非要是一个局部变量的地址,那么该局部变量一定要申明为static类型。如下:

    #include <stdio.h> 
    char *returnStr() 
    { 
        static char p[]="hello world!"; 
        return p; 
    } 
    int main() 
    { 
        char *str; 
         str=returnStr(); 
        printf("%s\n", str); 
     
        return 0; 
    } 
    

    数组是不能作为函数的返回值的,原因是编译器把数组名认为是局部变量(数组)的地址。返回一个数组一般用返回指向这个数组的指针代替,而且这个指针不能指向一个自动数组,因为函数结束后自动数组被抛弃,但可以返回一个指向静态局部数组的指针,因为静态存储期是从对象定义到程序结束的。如下:

    int* func( void )
    {
        static int a[10];
        ........
        return a;
    } 
    

    返回指向堆内存的指针是可以的

    
    char *GetMemory3(int num)
    {
    char *p = (char *)malloc(sizeof(char) * num);
    return p;
    }
    void Test3(void)
    {
    char *str = NULL;
    str = GetMemory3(100);
    strcpy(str, "hello");
    cout<< str << endl;
    free(str);
    

    程序在运行的时候用 malloc 申请任意多少的内存,程序员自己负责在何时用 free释放内存。动态内存的生存期由程序员自己决定,使用非常灵活。

    展开全文
  • 函数返回局部变量的指针或引用

    千次阅读 2018-05-16 23:17:53
    我们往往需要遵循如下原则:引用作为返回值,必须遵守以下规则:(1)不能返回局部变量引用。主要原因是局部变量会在函数返回后被销毁,因此被返回的引用就成为了"无所指"的引用,程序会进入未知状态。...
  • 千万不能返回局部变量引用??

    千次阅读 2013-10-29 20:43:40
    C++ Primer第7章函数一节,讲到返回时,“理解返回引用至关重要的是,千万不能返回局部变量的引用”, 意思是返回程序内部定义的变量时可能会出问题,因为当函数执行完毕后,将释放分配给局部对象的存储空间。 ...
  • 源之: ... int add1(int a, int b) ...add1的确返回了一个副本,如果sum是自定义的类类型,可以很明显看出拷贝构造函数在返回时被调用,对于内建类型没什么开销。...不能返回局部对象的引用
  • 所谓的不可以返回局部变量引用或指针,指的是不能返回局部变量引用或地址给引用或指针。事实上还是看该地址的位置是否在该函数的栈区,若是在栈区,函数调用结束,该地址就被释放了。尽管会出现栈地址上的值没被...
  • 一般的来说,函数是可以返回局部变量的。 局部变量的作用域只在函数内部,在函数返回后,局部变量的内存已经释放了。因此,如果函数返回的是局部变量的值,不...准确的来说,函数不能通过返回指向栈内存的指针(注意
  • 方法可以返回局部变量引用

    千次阅读 2016-04-14 20:02:05
    在C++中,我们知道函数不能返回局部变量引用,因为当函数调用结束后,局部变量会随着函数一起被销毁,因此局部变量引用作为返回值实际上是指向空对象。  既然如此,为什么在Java中可以返回局部变量引用呢?...
  • 当函数被调用时,函数入栈,当函数调用完成之后,系统负责把函数占用栈内存自动释放,所以存在栈中的局部变量的占用的内存得到释放,如果此时把当前局部变量的指针或引用返回给外部,外部函数得到的只是一个野指针...
  • //常整型cn被初始化为i+2=4好理解 整型引用ir怎么能引用一个构造函数内的局部变量(形参i)呢??? //正解:引用的本质是指针 数据成员ir引用局部变量形参i其实是指向了局部变量i定义时分配的内存 // 构造函数退出...
  • 书上都说不能返回局部变量引用或局部指针,说这种行为危险,但又没讲具体原因,那么今天就来看看这种行为的具体细节 PS:下面含有AT&T汇编内容,未学过汇编的朋友可以跳过直接看结论 先放一个实验用函数,即...
  • C++ Primer第7章函数一节,讲到返回时,“[color=#FF0000]理解返回引用至关重要的是,千万不能返回局部变量的引用[/color]”, 意思是返回程序内部定义的变量时可能会出问题,因为当函数执行完毕后,将释放分配给...
  • 大原则:不要在自动变量(不管是表达式中间结果的临时变量(如果它不能保证总优化到寄存器中)还是源程序中有明确名字的auto变量)生命期结束后还试图解引用它。 局部变量作为返回值时,一般是系统先申请一个临时对象...
  • C++中函数返回局部变量引用的问题

    千次阅读 2015-12-01 23:58:06
    初学C++, 看到书上及网上说函数返回值不能为指向函数局部变量的指针或者引用, 因为局部变量会在函数结束后销毁, 那么指向其位置的指针和引用就失效了, 有风险. 针对Deitel书上的习题, 写一个40位整数的四则运算, ...
  • 可以有空指针,但不能有空引用引用必须连接到一块合法的内存。 引用一旦被初始化为某对象,就不能被指向到另一个对象,而指针可以在任何时候指向到另一个对象。 引用必须在创建时被初始化。指针可以在任何时间被...
  • C++中应该返回局部变量的地址

    千次阅读 2017-11-24 19:20:15
    在Effective C++中明确指出:不应该返回局部变量引用,原因在于:局部变量会在函数返回后被销毁,因此被返回的引用就成为了”无...既然不能返回局部变量引用,如下所示,这样做是不合理的:int &getRefer() { int
  • 书上说不能返回局部变量的应用是因为函数在执行完后,系统就释放了局部变量的存储空间。有一点不太明白:函数执行完不就是执行完return语句才叫做执行完吗?那么执行return语句的时候函数还没有执行完。那么局部变量...
  • C++函数返回局部变量

    2018-08-31 15:10:11
    函数不能返回指向栈内存的指针或者引用 原因:返回值是拷贝值,局部变量的作用域为函数内部,函数执行结束,栈上的局部变量会销毁,内存释放。 可返回的局部变量: 1.返回局部变量本身 int sum(int a, int b) {...

空空如也

空空如也

1 2 3 4 5 ... 18
收藏数 348
精华内容 139
关键字:

局部变量不能返回引用