精华内容
下载资源
问答
  • 局部变量作为返回值
    2019-09-10 14:41:49

    参考:《C语言程序设计(苏小红)》P334-351  动态内存分配

    char *strA()

    {

      char str[] = "hello word";

      return str;

    }

    上述程序有什么问题?

    简单的来说,str是个局部变量的地址,作为返回值,有可能被提前回收。

    那么局部变量可以作为函数的返回值吗,这个问题不能一概而论。局部变量作为返回值时,一般是系统先申请一个临时对象存储局部变量,也就是找个替代品,这样系统就可以回收局部变量,返回的只是个替代品。

    了解完局部变量返回的过程,那么如果返回的是一个基本类型的变量,比如:

    int a;

    a = 5;

    return a;

    那么就会有一个临时对象也等于a的一个拷贝,即5返回,然后a就被销毁了。尽管a被销毁了,但它的副本5还是成功地返回了,所以这样做没有问题。

    那么如果是指针,这么返回就问题很大,因为你返回的局部变量是地址,地址虽然返回了,但地址所指向的内存中的值已经被回收了,你主函数再去调,就有问题了。这个问题也是可以解决的,可以把局部变量变为静态变量或者全局变量,这样就不存放在栈中了,而是存放在静态存储区,不会被回收。

     

    char str[] = "hello word";//分配一个局部变量

    char *str= "hello word";//分配一个全局变量

    更多相关内容
  • 局部变量作为返回值

    千次阅读 2019-04-09 22:54:52
    一般来说,函数是可以返回局部变量的,局部变量的作用域只在函数内部,在函数返回后,局部变量的内存已经释放了。因此,如果函数返回的是局部变量的值,不涉及地址,程序不会出错。但是如果返回的是局部变量的地址...

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

    #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!"是一个字符串常量,存放在只读数据段,把该字符串常量存放的只读数据段的首地址赋值给了指针,所以return Str函数退出时,该字符串常量所在内存不会被回收,故能够通过指针顺利无误的访问。

    #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释放内存。动态内存的生存期由程序员自己决定,使用非常灵活

    展开全文
  • 一般的来说,函数是可以返回局部变量的。 局部变量的作用域只在函数内部,在函数返回后,局部变量的内存已经释放了。因此,如果函数返回的是局部变量的值,不涉及地址,程序不会出错。但是如果返回的是局部变量的...

    一般的来说,函数是可以返回局部变量的。 局部变量的作用域只在函数内部,在函数返回后,局部变量的内存已经释放了。因此,如果函数返回的是局部变量的值,不涉及地址,程序不会出错。但是如果返回的是局部变量的地址(指针)的话,程序运行后会出错。因为函数只是把指针复制后返回了,但是指针指向的内容已经被释放了,这样指针指向的内容就是不可预料的内容,调用就会出错。准确的来说,函数不能通过返回指向栈内存的指针(注意这里指的是栈,返回指向堆内存的指针是可以的)。
    下面以函数返回局部变量的指针举几个典型的例子来说明:
    01.
    #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返回的是值,因此返回一个局部变量是可以的,无论自动还是静态,

    因为这时候返回的是这个局部变量的值,但不应该返回指向局部自动变量的指针,因为函数调用结束后该局部自动变量

    被抛弃,这个指针指向一个不再存在的对象,是无意义的。但可以返回指向局部静态变量的指针,因为静态变量的生存

    期从定义起到程序结束。

    04.如果函数的返回值非要是一个局部变量的地址,那么该局部变量一定要申明为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;   
    

    }

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

    return a;
    }

    06.返回指向堆内存的指针是可以的
    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释放内存。动态内存的生存期由程序员自己决定,使用非常灵活。

    2.参考:https://www.cnblogs.com/xuhj001/p/3436175.html

    展开全文
  • golang 局部变量地址作为返回值的问题 func createNode(v int) *node{ return &node{value:v} } func main(){ var root *node root=createNode(10) ... } 在c/c++语言中,以上的代码逻辑显然有问题,...

    golang 局部变量地址作为返回值的问题

    func createNode(v int) *node{
    	return &node{value:v} 
    }
    
    func main(){
    	var root *node
    	root=createNode(10)
    	...
    }
    

    在c/c++语言中,以上的代码逻辑显然有问题,createNode函数中创建了一个局部变量(空间分配在栈上),并将其地址返回。但是当函数退出后 该局部变量被回收,因此函数返回的地址显然无效的。


    但是在go语言中这么做是可以正常使用的。


    原因即go语言编译器会做逃逸分析(escape analysis),自动决定把一个变量分配在栈上还是堆上,当发现变量的作用域没有跑出函数范围,就在栈上,反之则必须分配在堆上。


    需要注意的是,对于动态new出来的局部变量,编译器也会根据是否有逃逸行为来决定是分配在堆还是栈,而并非直接分配在堆中。


    参见:

    How do I know whether a variable is allocated on the heap or the stack?
    
    From a correctness standpoint, you don not need to know. Each variable in Go exists as long as there are references to it. The storage location chosen by the implementation is irrelevant to the semantics of the language.
    
    The storage location does have an effect on writing efficient programs. When possible, the Go compilers will allocate variables that are local to a function in that function's stack frame. However, if the compiler cannot prove that the variable is not referenced after the function returns, then the compiler must allocate the variable on the garbage-collected heap to avoid dangling pointer errors. Also, if a local variable is very large, it might make more sense to store it on the heap rather than the stack.
    
    
    展开全文
  • 一个c++程序--函数中的局部变量返回值吗?? #include <stdio.h> #include <iostream.h> int f1(int i) { int s = 2; //局部变量,其只在本函数之内存在。 s = s +i; cout<<s<<endl; ...
  •  局部变量的作用域只在函数内部,在函数返回后,局部变量的内存已经释放了。因此,如果函数返回的是局部变量的值,不涉及地址,程序不会出错。但是如果返回的是局部变量的地址(指针)的话,程序运行后会出错。因为...
  • 局部变量作为返回值问题

    千次阅读 2014-04-23 18:10:57
    函数返回局部变量,是返回局部变量的值。但指针(或地址)是一种特殊的值,所以返回局部指针变量需要特别注意。正确情况下,作为函数返回值的局部指针,其所指向对象的作用域应该是调用者作用域、全局或静态常量区;...
  • C++函数返回值局部变量

    千次阅读 2017-11-30 21:45:28
    C++函数的返回值局部变量时,该返回值可能是值类型、指针类型和引用类型。 以自定义类型MyStruct为例: struct MyStruct { int x; int y; }; 1 返回值是自定义结构的值类型 定义一个返回值为MyStruct的函数...
  • 写了一个单链表,然后遇到一道题目 ...思索半天,原来是因为把函数内部的变量作为返回值而出现了问题 解决:把要做返回值的对象,改成函数调用时需要传进来的参数,返回值不要了,写成void,完美。 ...
  • 然后可以知道当在一个被调用的函数中声明一个局部指针变量,并让其作为这个函数的返回值,这个时候gcc编译会通过,但是运行时就会崩溃,原因就是使用了野指针,而这个野指针的产生原因就是因为局部变量指针返回的...
  • 请教大神如下问题:根据C++的内存管理可以知道,在函数里面创建的对象是作为局部变量的,那么这个对象就会在 函数结束的时候被回收。但是如果将这个对象作为返回值返回出去呢?一样会被回收吗?
  • 一般的来说,函数是可以返回局部变量的,但是要注意几种情况。 局部变量的作用域只在函数内部,在函数返回后,局部变量的内存已经释放了。因此,如果函数返回的是局部变量的值,不涉及地址,程序不会出错。但是如果...
  • c++中将局部变量的引用作为返回

    千次阅读 2018-11-05 18:57:21
    c++中可以将引用作为返回值,比如下面这个函数 int &amp;c() { int a = 2; cout &lt;&lt; "a的地址为:" &lt;&lt; &amp;a &lt;&lt; endl; return a; } 局部变量a的...
  • 否则结果可能正确,但存在风险。跳出函数后,局部变量已经没有作用域,不受控了,可能内存又分配给别的变量,内容被修改。
  • 函数返回局部指针变量是否可行?  我们大家都知道指针函数的返回指针不能指向函数内的自动变量,如果需要返回函数的内部变量的话,就需要将该变量声明为静态变量。为什么函数能够返回 静态变量的地址而...
  • 一般的来说,函数是可以返回局部变量的。 局部变量的作用域只在函数内部,在函数返回后,局部变量的内存已经释放了。因此,如果函数返回的是局部变量的值,不涉及地址,程序不会出错。但是如果返回的是局部变量的...
  • F.48 不要返回使用std:move从局部变量获得的右值引用 Reason(原因) With guaranteed copy elision, it is now almost always a pessimization to expressly use std::move in a return statement...
  • C语言-参数-返回值-局部变量-数组: ​ 返回值 char Funtion(){ //10000行代码 return 10; } //c语言角度:这里定义的函数类型是char(字符型),表示我将返回的的数据是一个字符型数据 //汇编语言角度:我创建了...
  •  1、一个局部的shared_ptr 作为返回值过程:当shared_ptr 被创建的时候,自身的引用计数 +1,当前引用计数为 1 , 按值返回以后 引用计数 + 1 (拷贝构造函数,就是可以理解为基础类型的拷贝),当前引用计数为 2 ...
  • 局部变量和成员变量1.定义的位置不一样【重点】局部变量:在方法的内部成员变量:在方法的外部,直接写在类当中2.作用范围不一样【重点】局部变量:只有方法当中才可以使用,出了方法就不能再用成员变量:整个类全都...
  • Python入门(二)全局变量与局部变量变量的引用三级目录函数的参数与递归面向对象异常模块魔法方法、迭代器、生成器文件 这部分内容承接Linux入门与python入门(一)的内容,是我在python入门学习的第三篇笔记。 在...
  • 函数的调用以及完成调用的过程是函数在栈内存中入栈和出栈的过程,当函数被调用时,函数入栈,当函数调用完成之后,系统负责把函数占用栈内存自动释放,所以存在栈中的局部变量的占用的内存得到释放,如果此时把当前...
  • 【C++基础之三】函数中局部变量的返回

    万次阅读 多人点赞 2013-09-10 14:45:11
    一般说来,函数中是可以进行局部变量的返回的,不然岂不是全部要用全局变量,如果使用了全局变量,那还有必要进行返回吗?那函数就没有它存在的意义了!但是要注意了,这里所谓的局部变量的返回很有内涵,什么样的值...
  •  局部变量的作用域只在函数内部,在函数返回后,局部变量的内存已经释放了。因此,如果函数返回的是局部变量的值,不涉及地址,程序不会出错。但是如果返回的是局部变量的地址(指针)的话,程序运行后会出错。因为...
  • 局部变量返回值 拷贝构造函数发生时机 传递引用和传递对象区别 返回引用和返回变量 局部变量返回值 函数执行过程是main函数先压栈然后函数,出栈的顺序相反,返回值会产生匿名变量(作为中间变量),至于这个...
  • 当函数返回值为数组(局部变量)时,局部变量存储在栈中,其作用域只在函数内部,由编译器自动分配释放; 当函数调用结束时,栈指针回退,局部变量内存被释放,此时再引用原来的局部变量就会出现不可预见的结果。 ...
  •   首先需要明白一件事情,临时变量,在函数调用过程中是被压到程序进程的栈中的,当函数退出时,临时变量出栈,即临时变量已经被销毁,临时变量占用的内存空间没有被清空,但是已经可以被分配给其他变量了,所以有...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 179,617
精华内容 71,846
关键字:

局部变量作为返回值