精华内容
下载资源
问答
  • 返回局部变量指针

    2011-12-19 09:43:19
    返回局部变量指针 一般我们都知道不能返回局部变量的指针,但很多人知道其然,不知道所以然,那么接下来我们分析一下,先看两段代码 /*test1.c*/ #include char* get_str() {  char str[] = {...
    
    

    返回局部变量指针

    一般我们都知道不能返回局部变量的指针,但很多人知道其然,不知道所以然,那么接下来我们分析一下,先看两段代码

    /*test1.c*/

    #include <stdio.h>

    char* get_str()
    {
        char str[] = {"hello"};
        return str;
    }


    int main()
    {
        char* p = get_str();
        printf("%s/n", p);
        return 0;
    }

     

    ====================

    /*test2.c*/

    #include <stdio.h>

    char* get_str()
    {
        char *str = {"hello"};
        return str;
    }


    int main()
    {
        char* p = get_str();
        printf("%s/n", p);
        return 0;
    }

     

    test2.c运行是没有问题的,也可以打印出正确的值,而test1.c却是错误的,打印出来的值和预期的完全不一样。他们都是返回了局部变量的指针,为什么会有差异呢,我们仔细看代码,发现他们只有一个地方不一样,那就是test1.c 里面str是一个数组,test2.c里面str是一个指针。原因就在这,str指针,其值是一个常量,而常量是放在数据段里面的,即便函数返回了,数据段里面的常量数据也还会在,直到程序结束才会消失,所以我们可以打印出来。

    而对于数组来说,它是一个局部变量,是放在栈里面的,函数返回之后,str指向的空间还是在的,如果我们打印出它的地址还是没有变。那么为什么内容会变掉呢,难道是系统会把栈中的数据清除,答案是否定的,因为这样做会消耗系统的资源,而且没有任何好处,下次用到这块内存还是会进行初始化的。打印出来的内容变掉是因为printf本身也是一个函数,也会进行参数的压栈,在压栈的过程中会把原来str指向的空间覆盖掉,也就改变了其中的值。如果我们在get_str之后,不调用任何函数并不创建新的局部变量(严格的说是不使栈继续往下增长),这个时候p指向的内容还是没变的。

    展开全文
  • 同事做code review的时候说这个可能有问题,第一反应想到的是返回局部变量指针的问题 但又感不太对,这个返回的是程序静态区域里常量的指针,应该是ok的。 百度了一下找的问题困惑的原因了,嘿嘿

    这两天coding的时候被一个小问题困惑了一下

    #define STR “abcd”

    static inline const char *GetStr()

    {

    return STR;

    }

    同事做code review的时候说这个可能有问题,第一反应想到的是返回局部变量指针的问题

    但又感不太对,这个返回的是程序静态区域里常量的指针,应该是ok的。

    百度了一下找的问题困惑的原因了,嘿嘿

    char *GetStr()

    {

    // char str[] = STR; --<这种返回才是我开始担心的局部变量指针的返回

    char *str = STR; --<返回的是STR的地址,就是上面说的静态区域中的地址

    return str;

    }

    这个也是指针和数组在应用的区别之一吧。

    后来跟同事讨论一下他的担忧。

    呵呵,他那是担忧如果程序尝试更改这个指针指向的字符串的数据时会引起程序崩溃。

    额,这个也是程序健壮性的一种concern吧,保留他的意见。

     

    展开全文
  • 我们大家都知道指针函数的...为什么函数能够返回 静态变量的地址而不能返回局部自动变量的地址,到底什么样的对象能够返回其地址,而什么样的对象不能够返回其地址?静态变量与局部自动变量的主要区别是什 么? ...

    转载于:https://www.cnblogs.com/mascotxi/p/4394893.html

    我们大家都知道指针函数的返回指针不能指向函数内的自动变量,如果需要返回函数的内部变量的话,就需要将该变量声明为静态变量。为什么函数能够返回 静态变量的地址而不能返回局部自动变量的地址,到底什么样的对象能够返回其地址,而什么样的对象不能够返回其地址?静态变量与局部自动变量的主要区别是什 么?

         要想明白这些就需要理解程序的内存布局情况

         程序的存储区域分为:代码段、只读数据段、已初始化的读写数据段、未初始化的数据段、堆、栈。

         1、代码段(只读属性)、只读数据段、已初始化的读写数据段、未初始化的数据段都属于静态区域

         2、堆内存只在程序运行时出现,一般有程序员分配和释放。

         3、栈内存只在程序运行时出现,在函数内部使用的变量,函数参数以及返回值将使用栈空间。     

           到底存储在静态区域和存储在栈区域的对象在返回指针的函数中有什么本质区别,为什么存储在静态区域的静态变量就能够返回其地址,而存储在栈区域的自动变量不能返回其地址?  

           主要在于他们的管理机制不同,存储在静态区域的对象的生存周期是主函数的生存周期,而存储在栈区域的对象生存周期为指针函数开始运行到指针函数结束,当指 针函数结束时存储在栈区域的对象生存周期也就结束,其地址也变成无效地址。栈空间由编译器自动分配和释放,函数结束时其栈空间释放内存。堆区域一般由程序 员来控制其生存周期。因此,指针函数返回的指针能够指向静态区域的变量而不能指向自动局部变量。

          当函数使用指针作为返回值时,它可以指向静态区域的地址,可以指向堆内存的地址,也可以指向函数调用者的栈空间,但是它不可以指向一个函数内部栈内存的地址

          因此,能不能返回局部指针变量,不在于这个指针变量的类型和性质(不在于该指针是不是局部指针变量),而在于该指针指向的对象的类型和性质。如果该指针指向函数内部的栈空间,则程序非法,如果指向静态区域的地址,则合法。

          因此,判断指针函数返回值是否合法,应该首先看看该返回指针变量指向的对象的存储区域,即该指针指向的区域。透过现象看本质,不同区域的对象本质区别在于 其的生存周期的有效性不同,判断返回的指针值是否有效合法,最本质应该看看该指针指向的对象的生存周期在函数结束后是否有效。如果该对象的生存周期长于指 针函数的生存周期,则该指针返回值合法,否则,该指针的值为非法地址。即使该指针指向堆区域的地址但在指针函数结束时,堆已释放,则该函数的返回地址仍为非法。

    展开全文
  • [img=https://img-bbs.csdn.net/upload/201404/20/1397962698_628977.jpg][/img] 如图,为什么两个运行结果不同?求大神指导
  • C++函数返回局部变量指针的问题

    千次阅读 2015-11-08 16:48:34
    函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。  来CSDN很久了,一直都想写点东西,今天终于出手了。...

    讲这个问题之前要先简单讲一下C++的内存管理。

    更详细的内容可以参考这篇文章《C++内存管理》。


    C++程序的内存被分为堆(heap),栈(stack),全局/静态存储区,自由存储区和常量存储区。

    1)堆(heap):new的都存放在这里,属于动态分配,如果在程序中调用delete释放掉,那么将一直存在,直到程序结束,由程序释放掉。

    2)栈(stack):由系统自动分配,形参和局部变量均存储在这里,函数退出时该栈自动销毁。

    3)全局/静态存储区:程序一开始执行即分配,生命周期持续到程序结束,存放全局变量,静态变量。

    4)自由存储区域:与堆的区别在于存放的是malloc的。

    5)常量存储区:顾名思义,存放常量的存储区。


    明白了C++的内存管理,接下来函数调用过程就比较好理解了。

    注意:栈空间是从高地址向低地址增长的。所以压栈即表示栈顶指针变小,而出栈则相反。

    函数调用者维护了一个栈空间(stack),拥有栈底指针ebp和栈顶指针esp。


    调用函数时,栈变化过程简单描述如下:

    1)先将函数返回地址ret压栈,即函数执行完毕后将从哪里继续执行下去

    2)将ebp压栈

    3)讲esp赋值给ebp

    4)将函数局部变量压栈


    函数执行完毕后,栈变化过程如下:

    1)函数局部变量出栈

    2)ebp出栈,恢复ebp的值

    3)函数返回地址出栈


    从以上的变化过程可以看到,函数调用者通过操作ebp和esp的值变化来维护栈的变化。即是,虽然函数执行完毕后栈“销毁”了,但在重入之前,存储在栈中的数据仍然存在!这个时候,通过指针来访问该位置仍然可以获得正确的值!

    但是为什么不推荐使用这种方式来获得局部变量的值呢?原因也是显而易见的,栈随时会被重入!重入之后,对应位置的值变成了不可预测,访问它会导致不可预测的后果。

    那在什么情况下可以通过函数返回指针的方式来访问函数局部变量呢?参照C++的内存管理,答案很明显,new的变量在函数结束之后仍然可以通过指针“安全”地访问!但这其实带来了新的问题:你要负责管理这个变量的生命周期或者任由它生存到程序结束(可能白白占用了内存!)

    一个简单的例子如下:

    1. #include <iostream>  
    2. using namespace std;  
    3.   
    4. int func1(int param)  
    5. {  
    6.     int local_param = param;  
    7.   
    8.     return local_param;  
    9. }  
    10.   
    11. int* func2(int param)  
    12. {  
    13.     int local_param = param;  
    14.   
    15.     return &local_param;  
    16. }  
    17.   
    18.   
    19. int *func3(int param)  
    20. {  
    21.     int *new_param = new int(param);  
    22.   
    23.     return new_param;  
    24. }  
    25.   
    26.   
    27. int main()  
    28. {  
    29.     int *pNewVar = func3(3);  
    30.     int *pVar = func2(2);  
    31.   
    32.     cout << pVar << endl;  
    33.     cout << pNewVar << endl;  
    34.     cout << func1(1) << endl;  
    35.     cout << pVar << endl;  
    36.     cout << pNewVar << endl;  
    37.   
    38.     return 0;  
    39. }  

    网址:http://blog.csdn.net/linqiaqun/article/details/41978545?ref=myread





    全局变量


    作用域:全局作用域(全局变量只需在一个源文件中定义,就可以作用于所有的源文件。) 
    生命周期:程序运行期一直存在 
    引用方法:其他文件中要使用必须用extern 关键字声明要引用的全局变量。 
    内存分布:全局数据区 
    注意:如果在两个文件中都定义了相同名字的全局变量,连接出错:变量重定义 
    例子: 
    + expand sourceview plaincopy to clipboardprint?//defime.cpp   
    int g_iValue = 1;  
      
    //main.cpp   
    extern int g_iValue;  
      
    int main()  
    {  
        cout << g_iValue;  
        return 0;  
    }  
    //defime.cpp
    int g_iValue = 1;


    //main.cpp
    extern int g_iValue;


    int main()
    {
        cout << g_iValue;
        return 0;



     


    全局静态变量


     作用域:文件作用域(只在被定义的文件中可见。)
    生命周期:程序运行期一直存在
    内存分布:全局数据区
    定义方法:static关键字,const 关键字
    注意:只要文件不互相包含,在两个不同的文件中是可以定义完全相同的两个静态变量的,它们是两个完全不同的变量
    例子:
    + expand sourceview plaincopy to clipboardprint?const int iValue_1;  
    static const int iValue_2;  
    static int iValue_3;  
      
    int main()  
    {  
        return 0;  
    }  
    const int iValue_1;
    static const int iValue_2;
    static int iValue_3;


    int main()
    {
        return 0;



     


    静态局部变量


    作用域:局部作用域(只在局部作用域中可见)
    生命周期:程序运行期一直存在
    内存分布:全局数据区
    定义方法:局部作用域用中用static定义
    注意:只被初始化一次,多线程中需加锁保护
    例子:
    + expand sourceview plaincopy to clipboardprint?void function()  
    {  
        static int iREFCounter = 0;  
    }  
    void function()
    {
        static int iREFCounter = 0;



     


    局部变量


    作用域:局部作用域(只在局部作用域中可见)
    生命周期:程序运行出局部作用域即被销毁
    内存分布:栈区
    注意:auto指示符标示
          还有一点要说明,掌握static关键字的使用很关键。以下是引用别人的一些经验之谈:


    Tips:


    若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
    若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
    设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题,因为他们都放在静态数据存储区,全局可见;
    如果我们需要一个可重入的函数,那么,我们一定要避免函数中使用static变量(这样的函数被称为:带“内部存储器”功能的的函数)
    函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。 


    来CSDN很久了,一直都想写点东西,今天终于出手了。水平有限,只能跟大家分享一些基础知识的总结,以共勉,共同提升。


    展开全文
  • Linux c 函数返回局部变量指针和返回局部指针变量 最近再看c语言实用之道这本书,对于其中的一段代码不太清楚,关于c函数返回局部指针变量与返回局部变量指针之间的区别,对于后者还是比较清楚的,前者一直有点...
  • 局部变量指针返回

    2020-07-16 12:17:53
    局部变量指针返回 https://blog.csdn.net/yang382197207/article/details/25873039
  • c语言 返回局部变量 局部指针 局部数组 内存四区模型  讨论这个问题之前,一定要理解堆区和栈区的工作原理,数据的存储区域(参考内存四区模型),另外一定不要返回局部对象或变量的引用和指针。 局部变量  ...
  •  不要返回局部变量的引用或指针,因为一旦函数结束,局部变量被释放,对局部变量的引用会指向不确定的内存,返回的指针变成了悬垂指针。    出现上述错误的原因很可能是因为调用rref结束后,分配给...
  • 返回局部对象的值时,会产生一个临时对象,局部对象将值拷贝给该临时对象(拷贝构造),所以当函数结束时,尽管局部已经析构了,但是它保存了一个副本在临时对象中,当函数接收完局部对象的值后(其实此时又进行了一...
  • /* * @Date: 2019-3-12 * @Author: tracycw ... 为什么不能返回局部指针变量,却可以返回局部变量 函数的局部变量用作返回值时,会生成一个局部变量的拷贝用作返回值,之后局部变量会被系统回收, ...
  • 一般的来说,函数是可以返回局部变量的。局部变量的作用域只在函数内部,在函数返回后,局部变量的内存已经释放了。因此,如果函数返回的是局部变量的值,不涉及地址,程序不会出错。但是如果返回的是局部变量的地址...
  • 返回局部变量指针

    2014-06-11 21:37:31
    返回局部变量时,函数将值复制保存给diaoy
  • 函数返回局部变量指针或引用

    千次阅读 2018-05-16 23:17:53
    我们往往需要遵循如下原则:引用作为返回值,必须遵守以下规则:(1)不能返回局部变量的引用。主要原因是局部变量会在函数返回后被销毁,因此被返回的引用就成为了"无所指"的引用,程序会进入未知状态。...
  • 如:int* 是一个指针变量类型指针变量和普通变量没有什么区别,指针32位四字节,里面保存的是一个内存空间的地址,就像一个整形变量int a, a就可以代表一个整数,一个指针变量int* p,p就可以代表一个地址数据,而*...
  • 返回局部指针变量

    2017-11-24 21:07:33
    返回值为数值时,返回局部变量可以,而返回值为引用或指针时,则存在风险。 局部变量是存在于栈中的,函数被调用时先在栈中为变量申请空间,调用完成释放变量空间。函数在返回参数的时候是这样的,先把要返回的数...
  • C++ primer中说“不要返回局部变量中的引用和指针” 但是今天一个简单的程序跑出来结果正确,很诧异…… int *fun1() { int i = 100; int *j = &i; return j; } int &fun2() { int i = 100; return i; } int ...
  • #include "stdlib.h" //应该为 char *test(char *ptr) { unsigned char i; //应该为unsigned int i;... //局部变量太大了,容易造成堆栈溢出; char *p, *q; for( i=0; i *1024; i++ ) //应该为i *1024; buf
  • c[]数组的存放地址是被传送出去了的,但是,由于c[]是局部变量, 在函数执行完成后,存放的内存空间就被释放,所以,在外部通过指针访问c[]数组时,指向的内存空间无效,而且还可能出现访问非法内存的危险。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,697
精华内容 678
关键字:

返回局部变量指针