精华内容
下载资源
问答
  • 结论:函数可以返回局部变量的...但是如果返回局部变量的地址,那么返回的是该局部变量地址的值拷贝,但是函数运行结束,该拷贝指针所指向的栈内容已经被释放即为野指针,对野指针所指向内容的操作都会造成段错误 ...

    结论:函数可以返回局部变量的值,但是不能返回指向栈内存的指针。
    原因:
    局部变量的作用域为函数内部,函数执行结束,操作系统会自动释放栈上的局部变量。并且函数返回的是局部变量的值拷贝。但是如果返回局部变量的地址,那么返回的是该局部变量地址的值拷贝,但是函数运行结束,该拷贝指针所指向的栈内容已经被释放即为野指针,对野指针所指向内容的操作都会造成段错误
    函数是可以返回指向堆内存的指针,但是这需要在调用者在函数外手动进行内存的释放,这样的接口很烂。可以通过指针传递来解决。

    展开全文
  • Go语言---函数返回局部变量地址

    千次阅读 多人点赞 2018-05-05 21:10:52
    一、C语言中返回函数中局部变量值和指针(1) 在...(2) 函数返回局部变量地址:局部变量内存分配在栈空间,因为函数返回后,系统自动回收了函数里定义的局部变量,所以运行时去访问一个被系统回收后的地址空间,一定就...

    一、C语言中返回函数中局部变量值和指针

    (1) 在C语言中,一个函数可以直接返回函数中定义的局部变量,其实在函数返回后,局部变量是被系统自动回收的,因为局部变量是分配在栈空间,那为什么还可以返回局部变量,其实这里返回的是局部变量的副本(拷贝)

    (2) 函数返回局部变量地址:局部变量内存分配在栈空间,因为函数返回后,系统自动回收了函数里定义的局部变量,所以运行时去访问一个被系统回收后的地址空间,一定就会发生段错误,这是C/C++语言的特点。内存空间分配在堆中即可。

    二、GO函数中返回变量,指针

    示例代码:

    package main
    
    import "fmt"
    
    func fun() *int {    //int类型指针函数
        var tmp := 1
        return &tmp      //返回局部变量tmp的地址
    }
    
    func main() {
        var p *int
        p = fun()
        fmt.Printf("%d\n", *p) //这里不会像C,报错段错误提示,而是成功返回变量V的值1
    }

    参考go FAQ里面的一段话:

    How do I know whether a variable is allocated on the heap or the stack?
    
    From a correctness standpoint, you don't 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.
    
    In the current compilers, if a variable has its address taken, that variable is a candidate for allocation on the heap. However, a basic escape analysis recognizes some cases when such variables will not live past the return from the function and can reside on the stack.

    意思是说go语言编译器会自动决定把一个变量放在栈还是放在堆,编译器会做逃逸分析(escape analysis),当发现变量的作用域没有跑出函数范围,就可以在栈上,反之则必须分配在堆。所以不用担心会不会导致memory leak,因为GO语言有强大的垃圾回收机制。go语言声称这样可以释放程序员关于内存的使用限制,更多的让程序员关注于程序功能逻辑本身。

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

    结论:

    函数内部局部变量,无论是动态new出来的变量还是创建的局部变量,它被分配在堆还是栈,是由编译器做逃逸分析之后做出的决定。
    展开全文
  • //局部变量存放在栈区,不要在函数中返回局部变量地址,函数退出后,局部变量的内存被系统自动释放 int* print() { int a = 10; return &a; } int main() { int *p = print(); cout<<*p<&...
    #include <iostream>
    
    using namespace std;
    
    //局部变量存放在栈区,不要在函数中返回局部变量的地址,函数退出后,局部变量的内存被系统自动释放
    int* print()
    {
    	int a = 10;
    	
    	return &a;	
    }
    
    int main()
    {
    		int *p = print();
    		cout<<*p<<endl;//第一次打印正确的值,是因为编译器做了一次保留;
    		cout<<*p<<endl;//第二次这个数据就不会保留了;
    	
    		return 0;
    }
    
    #include <iostream>
    
    using namespace std;
    
    //函数中申请堆区空间,由自己进行释放
    //指针a是一个局部变量指针,存放在栈区空间中,但指向堆区内存
    int* print()
    {
    	int *a = new int(10);
    	
    	return a;	
    }
    
    int main()
    {
    		int *p = print();//函数返回指针赋值给新的变量,函数局部变量a被自动释放
    		cout<<*p<<endl;//堆区空间可以一直被使用,直到被释放;
    		cout<<*p<<endl;
    	
    		delete p;
    		return 0;
    }
    
    
    
    
    #include <iostream>
    
    using namespace std;
    
    //不要返回局部变量的引用
    //局部变量存放在栈区空间中,函数退出后栈区空间被自动释放
    int& print()
    {
    	int a = 10;
    	int &b = a;
    	
    	return b;	
    }
    
    int main()
    {
    		int &a = print();
    		cout<<a<<endl;//第一次编译器会保留函数的返回值
    		cout<<a<<endl;//第二次值就会被释放掉了,防止后面使用引用
    		return 0;
    }
    
    
    展开全文
  • 因此,如果函数返回的是局部变量的值,不涉及地址,程序不会出错。但是如果返回的是局部变量地址(指针)的话,程序运行后会出错。因为函数只是把指针复制后返回了,但是指针指向的内容已经被释放了,这样指针指向的...
    一般的来说,函数是可以返回局部变量的。 局部变量的作用域只在函数内部,在函数返回后,局部变量的内存已经释放了。因此,如果函数返回的是局部变量的值,不涉及地址,程序不会出错。但是如果返回的是局部变量的地址(指针)的话,程序运行后会出错。因为函数只是把指针复制后返回了,但是指针指向的内容已经被释放了,这样指针指向的内容就是不可预料的内容,调用就会出错。准确的来说,函数不能通过返回指向栈内存的指针(注意这里指的是栈,返回指向堆内存的指针是可以的)。 
    

        下面以函数返回局部变量的指针举几个典型的例子来说明:

    1:

    1. #include <stdio.h>   
    2. char *returnStr()   
    3. {   
    4.     char *p="hello world!";   
    5.     return p;   
    6. }   
    7. int main()   
    8. {   
    9.     char *str;   
    10.     str=returnStr();   
    11.     printf("%s\n", str);   
    12.     return 0;   
    13. }  
    这个没有任何问题,因为"hello world!"是一个字符串常量,存放在只读数据段,把该字符串常量存放的只读数据段的首地址赋值给了指针,所以returnStr函数退出时,该该字符串常量所在内存不会被回收,故能够通过指针顺利无误的访问。

    2:

    1. #include <stdio.h>   
    2. char *returnStr()   
    3. {   
    4.     char p[]="hello world!";   
    5.     return p;   
    6. }   
    7. int main()   
    8. {   
    9.     char *str;   
    10.     str=returnStr();   
    11.     printf("%s\n", str);   
    12.     return 0;   
    13. }   
    "hello world!"是局部变量存放在栈中。当returnStr函数退出时,栈要清空,局部变量的内存也被清空了,所以这时的函数返回的是一个已被释放的内存地址,所以有可能打印出来的是乱码。 

    3:

    1. int func()  
    2. {  
    3.       int a;  
    4.       ....  
    5.       return a;    //允许  
    6. }                     
    7.   
    8. int * func()  
    9. {  
    10.       int a;  
    11.       ....  
    12.       return &a;    //无意义,不应该这样做  
    13. }   

    局部变量也分局部自动变量和局部静态变量,由于a返回的是值,因此返回一个局部变量是可以的,无论自动还是静态,

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

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

    期从定义起到程序结束。

    4:如果函数的返回值非要是一个局部变量的地址,那么该局部变量一定要申明为static类型。如下:
    1. #include <stdio.h>   
    2. char *returnStr()   
    3. {   
    4.     static char p[]="hello world!";   
    5.     return p;   
    6. }   
    7. int main()   
    8. {   
    9.     char *str;   
    10.      str=returnStr();   
    11.     printf("%s\n", str);   
    12.   
    13.     return 0;   
    14. }   
    5: 数组是不能作为函数的返回值的,原因是编译器把数组名认为是局部变量(数组)的地址。返回一个数组一般用返回指向这个数组的指针代替,而且这个指针不能指向一个自动数组,因为函数结束后自动数组被抛弃,但可以返回一个指向静态局部数组的指针,因为静态存储期是从对象定义到程序结束的。 如下:
    1. int* func( void )  
    2. {  
    3.     static int a[10];  
    4.     ........  
    5.     return a;  
    6. }   

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

    1. char *GetMemory3(int num)  
    2. {  
    3. char *p = (char *)malloc(sizeof(char) * num);  
    4. return p;  
    5. }  
    6. void Test3(void)  
    7. {  
    8. char *str = NULL;  
    9. str = GetMemory3(100);  
    10. strcpy(str, "hello");  
    11. cout<< str << endl;  
    12. free(str);  
    13. }  
    程序在运行的时候用 malloc 申请任意多少的内存,程序员自己负责在何时用 free释放内存。动态内存的生存期由程序员自己决定,使用非常灵活。
    展开全文
  • 最近遇到一个段错误,机器跑几天才会出一次,多线程,GDB 显示死在sem getvalue(),打印局部变量发现所有的局部变量地址都超大 变得不可访问,不知道大家有没有遇到过类似的段错误现象?
  • GO与C比较:指针函数返回局部变量地址的不同 C语言函数中如何返回变量与指针? 在C语言中,一个函数可以直接返回函数中定义的局部变量,其实在函数返回后,局部变量是被系统自动回收的,因为局部变量是分配在栈...
  • 最近keil中调试STM32程序时,出现的问题是局部变量冲掉了全局变量的数据。 查资料,原因是局部变量定义在栈中,栈在RAM区,由系统自动管理,查看map文件可以看到栈区空间位于在系统计算的实际需要的RAM大小的最后...
  • 浅谈C语言函数返回值--局部变量和局部变量地址

    千次阅读 多人点赞 2014-05-15 10:40:18
    编译警告程序返回局部变量地址,输出为乱码。因为fun返回的是局部变量的地址,真是拷贝了一份地址,地址所指向的内容在fun结束的时候已经释放,变量已经被销毁,现在根本不知道地址指向的内容的是什么。 如果确实...
  • 如题,使用GCC编译器时发现,局部变量地址总是从低地址向高地址分配,而dev c中局部变量却是从高地址向低地址分配的? “栈分配的方向是从高地址向低地址分配,但在变量内部地址是从低地址向高地址增长。”一直都...
  • int function() { int i,j ,x; } i,j,x的地址是按照顺序以四字节的间隔申请的吗?
  • 局部变量地址的返回

    千次阅读 2014-10-09 21:07:01
     就函数而言,返回局部变量地址这种做法是错误的,但是这个函数不管是在VS还是在gcc上编译时都只会有一个警告  局部变量地址在出了作用域后就没有意义了,可能被其他数据覆盖 ➜ 1009 git:(master...
  • 引用局部变量地址

    千次阅读 2008-07-14 21:12:00
    在主程序中,当程序执行完fFun之后,i做为局部变量是存放于栈上的,将i的地址返回给p;然后i出栈。进入gFun,gFun内有一个局部变量j,就入栈,占用刚才i占用的位置(这个不一定,根据编译器不同而不同)。则p指向j。...
  • MDK中变量地址重合问题     最近在使用MDK开发LPC1768的一个项目。利用的是MDK自动生成的启动代码,稍作修改后使用,在调试程序的时候,发现了大量的问题: 1. 程序中开有一个全局的数组,...
  • 1. 函数中的局部变量地址是无法返回的,返回会报出警告  为何会有这种情况? 我一开始不知道是怎么回事, 然后我就在网上搜索了一下, 发现了一个合理的解释:  因为想要返回局部变量的地址就必须用一个指向该类型的...
  • 11: int*p = &n1;//全局变量 00401019 C7 45 F8 30 29 41 00 mov dword ptr [ebp-8],offset n1 (00412930) 12: p = &n2;//局部变量 00401020 8D 45 FC lea eax,[eb...
  • C++中不应该返回局部变量地址

    千次阅读 2017-11-24 19:20:15
    在Effective C++中明确指出:不应该返回局部变量的引用,原因在于:局部变量会在函数返回后被销毁,因此被返回的引用就成为了”无所指”的引用,程序会进入未知状态。如果比较理解函数局部变量的作用域和生命周期,...
  •   基本概念: 作用域:起作用的区域,也就是可以工作的范围。...C语言中局部变量就分配在栈中。   局部变量  普通的局部变量定义的时候直接定义或者在前面加上auto void func1(void){&nbs...
  • C语言中局部变量地址覆盖问题

    千次阅读 2017-10-19 15:37:58
     在C语言的一个函数中定义了几个局部变量如A,B,C。当对其中一个变量A取地址并对该地址赋值时,如果赋值的地址大小超过A所占的空间大小,则其它的变量会被修改。 2.调试过程  把被改变的变量的地址和A的地址...
  • 关于java成员变量和局部变量

    万次阅读 多人点赞 2018-09-14 10:46:45
    1、成员变量和局部变量简述 在Java语言里,根据定义变量位置的不同,可以将变量分成两大类:成员变量(存在于堆内存中,和类一起创建)和局部变量(存在于栈内存中,当方法执行完成,让出内存,让其他方法来使用内存)...
  • 成员变量和局部变量同名 在同一个作用域内不允许定义同名的多个变量。   在一个方法内,可以定义和成员变量同名的局部变量或参数,此时成员变量被屏蔽。此时如果想要访问成员变量,可以通过 this 关键字来...
  • 1、局部变量能否和全局变量重名?  答:能,局部会屏蔽全局。要用全局变量,需要使用 ":: "  局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。对于有些编译器...
  • 因此,如果函数返回的是局部变量的值,不涉及地址,程序不会出错。但是如果返回的是局部变量地址(指针)的话,程序运行后会出错。因为函数只是把指针复制后返回了,但是指针指向的内容已经被释放了,这样指针指向的...
  • 全局变量局部变量静态全局变量、静态局部变量的区别   转自:http://hi.baidu.com/sindana/blog/item/06fe68171e364401c93d6ded.html 标签:全局变量 局部变量 静态全局变量 静态局部变量 ...
  • 概念首先得明白局部变量,静态局部变量,全局变量,静态全局变量这几个概念,以下面程序举例://main.cpp int a = 0; //全局变量 static int b=0;//静态全局变量 main() { int c; //局部变量 static int d;//静态...
  • 作用域可分为6种:全局作用域,局部作用域,语句作用域,类作用域,命名作用域和文件作用域。 存储域可分为2种:静态存储区和栈区,另:函数申请内存空间在堆区里面(这不在本文讨论范围之内)。 首先,从...
  • 全局变量局部变量静态全局变量、静态局部变量的区别转自:http://hi.baidu.com/sindana/blog/item/06fe68171e364401c93d6ded.html 标签:全局变量 局部变量 静态全局变量 静态局部变量 it ...
  • 全局变量、局部变量、静态全局变量、静态局部变量的区别 C++变量根据定义位置的不同,具有不同的作用域,作用域可分为6种:全局作用域,局部作用域,语句作用域,类作用域,命名作用域和文件作用域。 从作用域...
  • 静态局部变量具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在,它和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。...
  • Java局部变量final

    千次阅读 2018-10-26 09:25:36
    局部变量和形参带final。 在一个线程A中开起另一个线程B,如果线程B要使用线程A的局部变量,那么A的局部变量需要定义成final。理由:局部变量是线程内部共享的,每一个线程内的不能访问其他线程的局部变量,但是上诉...
  • 所以我们在书写C语言程序时候, 如果返回指针(变量地址),应该返回堆区或者全局区的,这样就可以避免这个”意想不到的”结果 reference: 原文:https://blog.csdn.net/u012222482/article/details/52458429 原文:...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 298,253
精华内容 119,301
关键字:

局部变量的地址