精华内容
下载资源
问答
  • C语言指针局部变量释放问题

    千次阅读 2019-03-11 21:01:02
    C语言指针局部变量释放问题1.问题代码2.一次改动3.理论4.佐证测试代码5.总结 1.问题代码 #include "stdio.h" #include "string.h&amp...


       一个朋友有次跟我探讨一段代码,其中涉及了局部变量被释放的问题,但是意外发现定义的局部指针变量在释放时候会有些奇怪的现象,借此我查找一些资料,写了测试佐证代码得出结论。不太清楚的朋友可以了解一下。


    1.问题代码

    #include "stdio.h"
    #include "string.h"
    int* get(int a ,int b)
    {
      int c = 0;
      c = a + b;
      printf("%p\n",&c);
      return &c;
    }
    
    int main(void)
    {
      int *p = get(4,5);
      printf("%p\n",p);
      return 0;
    }
    
    

    gcc 编译时警告已经显示
    在这里插入图片描述
    Waning:函数返回了一个局部变量的地址

    • 运行结果:
      在这里插入图片描述

    2.一次改动

        这里我对返回的地址用指针存放,返回这个指针地址

    #include "stdio.h"
    #include "string.h"
    int* get(int a ,int b)
    {
      int c = 0;
      c = a + b;
      int *d = &c;
      printf("%p\n",&c);
      return d;
    }
    
    int main(void)
    {
      int *p = get(4,5);
      printf("%p\n",p);
      printf("%d\n",*p);
      return 0;
    }
    
    
    
    • 运行结果:
      在这里插入图片描述
      》》》发现没有警告,而且地址相同,甚至值也对的

    但是经过测试发现,这个指针跟指向的值,其实都被回收了,只是没有人用而已,所以值才没有改变。

    3.理论

    -------------引用赵四老师:
        a) : 栈中的变量通常包括函数参数和函数里声明的临时变量。
        b) : 栈中的基本变量退出其作用域时,没有谁执行一段代码去释放/销毁/析构它所占用的内存,仅仅是没人再去理会的留在当前栈顶上方的若干遗留下来可被后续压栈操作覆盖的无用数据而已。
        c) : 而栈中的类变量退出其作用域时,会自动执行其析构函数

    4.佐证测试代码

    #include <stdio.h>
    int *global = NULL;
    int *f(int c)
    {
      int b = c;
      int *p1 = &b;
      global = &b;
      return p1;
    }
    
    int main()
    {
      int *p = f(6);
      printf("p_addr : %p\n",p);
      printf("p_num : %d\n",*p);
      printf("global_addr : %p\n",global);
      printf("global_num : %d\n",*global);
      printf("*f(7) return : %d\n",*f(7));
      printf("p_addr : %p\n",p);
      printf("p_num : %d\n",*p);
      printf("global_addr : %p\n",global);
      printf("global_num : %d\n",*global);
    }
    
    
    • 运行结果:
      ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190311205136665.png

    5.总结

        结果会发现,同一个地址,又被分配一次。

        其实就是说,再一次执行这个函数时,你上次用这个函数返回的地址跟指向的内存地址,又被分配使用了,所以那样的使用是不安全的,那个对的数据,只是遗留下来可被后续压栈操作覆盖的无用数据

        所以你访问一个被释放的局部变量,都是一个不安全的行为。返回可以返回数值,但是不能返回一个局部变量的地址

    展开全文
  • {char b[10] = "abcde";return b;}char *test1_ver2(void){static char b[10] = "abcde";...}char *test2(void){char c[10] = "abcde";char *pStr = c;return pStr;}char *test3(void){char *c = "abcdef";ret...

    {

    char b[10] = "abcde";

    return b;

    }

    char *test1_ver2(void)

    {

    static char b[10] = "abcde";

    return b;

    }

    char *test2(void)

    {

    char c[10] = "abcde";

    char *pStr = c;

    return pStr;

    }

    char *test3(void)

    {

    char *c = "abcdef";

    return c;

    }

    test1不能运行,甚至可能无法编译通过;因为char b[10] 是局部变量,其存放在栈上,在函数执行完成就会被释放。而返回它存放的地址,此时已经是可能是个非法地址。

    test1_ver2可以正确运行,在test1中,我们说test1不能运行或出现编译错误的原因是 b[]数组在函数执行结束后会被释放,如果我们再对其存放空间进行访问就会出错,此时我们定义static char b[10]; 将其存放在静态存储区,只有在程序运行结束后才会被系统回收,即使退出该函数,b[]数组存放的静态存储区始终存在,所以,我们再对其进行访问,不会出现错误

    test2可以运行。c[10]和*pStr均保存在栈中;该函数返回值是保存在pStr指针中的c数组在栈中的存放地址,当调用该函数时,该地址被复制到外部的指针变量中,然后,保存在栈上的c[]数组和pStr指针的内存空间被释放。c[]数组的存放地址是被传送出去了的,但是,由于c[]是局部变量, 在函数执行完成后,存放的内存空间就被释放,所以,在外部通过指针访问c[]数组时,指向的内存空间无效,而且还可能出现访问非法内存的危险。虽然这样能够运行,但是没有实际效果

    test3可以运行。*c指针c是保存在栈中,"abcdef"字符串保存在文字常量区,其存放空间,直到程序执行结束才会被系统回收。所以,返回它的地址是一个实际存在的有效地址。

    展开全文
  • C局部指针问题

    2021-03-16 15:01:46
    C局部指针问题代码片. 记录: 指针涉及两个内存: 1、指针本身内存 局部指针存放于栈上,当所处作用域消亡,会被自动销毁。 2、指针指向的内存 指针指向的内存位于堆上,即使指针所在作用域不存在了,该内存只要不被...

    C局部指针问题??记录:

    指针涉及两个内存:
    1、指针本身内存
    局部指针存放于栈上,当所处作用域消亡,会被自动销毁。

    2、指针指向的内存
    指针指向的内存如果是malloc则位于堆上,即使指针所在作用域不存在了,该内存只要不被释放则内存泄漏。

    char* test_location_pointer()
    {
        char *ch = "dasdasda";
        printf("a    %p\r\n",&ch);    //指针本身的地址
        printf("b    %p\r\n",ch);     //指针指向的地址
        
        return ch;
        //return &ch;    //编译器警告,返回了局部变量
    }
    

    编译器报警,局部指针。

    int main(void)
    {
        char *c = test_location_pointer();
        printf("c    %p = %ld\r\n\r\n",c,strlen(c));
        char *ch = test_location_pointer();
        printf("ch   %p = %ld\r\n",ch,strlen(ch));
        return 0;
    }
    

    结果:

    lestly@lestly-virtual-machine:~/桌面/code/pointer$ gcc pointer.c -o pointer
    lestly@lestly-virtual-machine:~/桌面/code/pointer$ ./pointer 
    a    0x7ffd69943e80
    b    0x5645bdeb1004
    c    0x5645bdeb1004 = 8
    
    a    0x7ffd69943e80
    b    0x5645bdeb1004
    ch   0x5645bdeb1004 = 8
    

    可以看到地址是不变,内容也不变,表明在堆上的内存依然存在。这个堆上的内存也不需要我们释放,系统会帮我们自动处理(未知??),一般我们只需要malloc和free配对即可。局部指针应该会被自动释放,但是它的地址也不变,是编译器优化吗??求解答。

    展开全文
  • C语言在子函数调用之后是要进行子函数中局部变量所占的内存进行释放的 全局变量在退出程序时释放 但是现在有个问题 如果全局变量是个指针,在子函数中重新赋值,那么子函数退出后,是否释放? 如下 int *i; ...
  • 关于C语言中返回局部指针变量

    千次阅读 2017-12-26 18:18:51
    关于C语言中函数返回局部指针变量出错。

    前言

    写这篇文章,是因为同学在leetcode上遇到了这样一个错误:
    - 题目:Two Sum
    - 代码如下:

    int* twoSum(int* nums, int numsSize, int target)
    {
        int i,j;
        int res[2];                                 /* 加上static之后正常运行 */
        for (i=0; i<numsSize; i++) {
            for (j=i; j<numsSize; j++) {
                if (nums[i]+nums[j]==target) {
                    res[0]=i;
                    res[1]=j;
                    break;
                } else {
                    continue;
                }
            }
        }
        return res;
    }
    

    - 运行时出现错误:

    load of null pointer of type 'const int'

    - Google之后发现,在声明res[2]的时候加上static就可以正常运行。于是在《The C Programming Language》(P70,4.6 静态变量)找到了相关内容:

    用static限定外部变量与函数,可以将其后声明的对象的作用域限定为被编译源文件的剩余部分。该外部变量/函数除了对该所在的文件可见外,其他文件都无法访问。
    用static声明内部变量,则该变量是某个特定函数的局部变量,只能在该函数中使用。但它与自动变量不同的是,不管其所在函数是否被调用,它一直存在,而不像自动变量那样,随着所在函数的被调用和退出而存在和消失。换句话说,static类型的内部变量是一种只能在某个特定函数中使用但一直占据存储空间的变量。

    分析上面的代码,函数返回了一个int类型的指针,但是报错却说是一个空指针。猜想是int res[2];的声明导致res是一个自动变量的数组指针,在退出该函数之后,res指针指向的内存被覆盖,所以导致出错。使用static进行声明,可以保证res[2]不会因为函数的退出而消失。下面进行验证。

    验证

    • 参考资料

      关于C语言中返回局部变量和局部指针变量

    • 平台和工具

      • Windows 10, Code::Blocks-16.01(mingw)
    • 测试代码

      
      #include <stdio.h>
      
      char *test1(void)
      {
          /*
           * 编译时出现warning,运行时打印乱码。
           * char b[10] 是局部变量,其存放在栈上,在函数执行完成就会被释放。
           * 而返回它存放的地址,此时已经是可能是个非法地址。
           * 运行时打印乱码,验证了b[10]的内存被释放。
           */
          char b[10] = "abcde";
          return b;                     // warning: function returns address of local variable [-Wreturn-local-addr]|
      }
      char *test1_ver2(void)
      {
          /*
           * 正确运行。
           * 定义static char b[10]; 将其存放在静态存储区,只有在程序运行结束后才会被系统回收。
           * 即使退出该函数,b[]数组存放的静态存储区始终存在,所以,我们再对其进行访问,不会出现错误。
           */
          static char b[10] = "abcde";
          return b;
      }
      char *test2(void)
      {
          /*
           * 可以运行,但打印出错。
           * c[10]和*pStr均为自动变量,保存在栈中;函数返回时,c[]数组和pStr指针的内存空间被释放
           * 所以,在外部访问c[]数组时,指向的内存空间无效。
           */
          char c[10] = "abcde";
          char *pStr = c;
          return pStr;
      }
      char *test3(void)
      {
          /*
           * 正确运行。
           * 指针c保存在栈中,但是"abcdef"字符串保存在常量区,其内存空间直到程序运行结束才会被释放。
           * 所以,返回的地址是一个实际存在的有效地址。
           */
          char *c = "abcdef";
          return c;
      }
      int main()
      {
          char *p_test1, *p_test1_ver2, *p_test2, *p_test3;
          p_test1 = test1();
          p_test1_ver2 = test1_ver2();
          p_test2 = test2();
          p_test3 = test3();
      
          printf("test1:%s\n", p_test1);
          printf("test1_ver2:%s\n", p_test1_ver2);
          printf("test2:%s\n", p_test2);
          printf("test3:%s\n", p_test3);
      
          return 0;
      }
    • 输出结果1:

      test1:[w骾      A
      test1_ver2:abcde
      test2:`
      test3:abcdef
    • 输出结果2:

      test1:[w詡?
      test1_ver2:abcde
      test2:`
      test3:abcdef
    展开全文
  • 我们大家都知道指针函数的返回指针不能指向函数内的自动变量,如果需要返回函数的内部变量的话,就需要将该变量声明为静态变量。为什么函数能够返回 静态变量的地址而不能返回局部自动变量的地址,到底什么样的对象...
  • 局部变量的作用域只在函数内部,在函数返回后,局部变量的内存已经释放了。因此,如果函数返回的是局部变量的值,不涉及地址,程序不会出错。但是如果返回的是局部变量的地址(指针)的话,程序运行后会出错。因为函数...
  • 返回局部指针

    2016-09-01 12:37:41
    以前经常在C++/c 中听到,不能去返回局部指针。 导致现在ios,和cocos的开发都有一定的阴影。 当时对这句话的含义没有理解完全。所谓不能返回的局部指针。这个指针指向的一定是基础数据类型,在准确点指向的数据是...
  • C语言指针动态内存的申请和释放

    千次阅读 2020-08-20 21:10:28
    当程序不需要这个变量时,就需要把申请的这块内存释放掉,这就是内存的释放。往往内存的申请和释放是一起使用的,只要有内存的申请,就要有内存的释放,避免出现内存泄漏。 C语言指针的申请: (1).在C语言中...
  • 输出结果如下图: ...当子函数返回后,局部变量已经超出了作用域啊,为什么在main()函数中还能通过指针rp间接访问变量x呢??为什么第一次访问可以输出12,第二次访问就内存释放了呢,输出一个随机数????
  • c语言 返回局部变量 局部指针 局部数组 内存四区模型  讨论这个问题之前,一定要理解堆区和栈区的工作原理,数据的存储区域(参考内存四区模型),另外一定不要返回局部对象或变量的引用和指针。 局部变量  ...
  • char *test1(void) { char b[10] = "abcde"; return b; } char *test1_ver2(void) { static char b[10] = "abcde"; return b; } char *test2(void) ...char c[10] = "abcde"; char *pStr = c; return p
  • /* * @Date: 2019-3-12 ... 局部变量、局部指针变量的返回 为什么不能返回局部指针变量,却可以返回局部变量 函数的局部变量用作返回值时,会生成一个局部变量的拷贝用作返回值,之后局部变量会被系统回收, ...
  • C语言中野指针

    2018-10-17 16:15:59
    野指针 野指针通常是因为指针变量中保存的值不是一个合法的内存地址而造成的 野指针不是NULL指针,是指向不可用...局部指针变量没有被初始化 #include &lt;stdio.h&gt; #include &lt;string.h&gt...
  • 子函数运行结束时,所有局部变量的内存单元会被系统释放。形参和函数内部的局部变量的生命期和作用域都是在函数内部( static变量的生命期除外)。 在C中,函数被调用时的传参方式有两种形式:传值和传址。 传址...
  • 局部指针变量

    2018-04-12 14:48:39
    char *test1(void){char b[10] = "abcde";return b;}char *test1_ver2(void){static char b...}char *test2(void){char c[10] = "abcde";char *pStr = c;return pStr;}char *test3(void){char ...
  • C语言指针讲解

    2021-03-14 00:45:55
    “野指针”指的是指针变量中的值是非法的内存地址,但“野指针”不是空指针(NULL),“野指针”指向的内存是不可用的,“野指针”往往会造成内存越界、段错误等问题 补充:合法的内存地址包括定义的变量的地址、...
  • C++智能指针与返回局部指针测试

    千次阅读 2016-04-02 09:26:10
    需要再调用delete。对象删除会自动调用析构函数。 这里只记录:unique_ptr 与shared_ptr auto_ptr已经被unque_ptr替换 weak_ptr不是特别常用。 unique_ptr 是唯一的智能指针管理,同时只有一个记录,不可直接...
  • C/C++】原来这样做就能避免C语言悬垂指针问题

    千次阅读 多人点赞 2020-04-11 19:04:02
    如何避免4.1 C语言4.2 C++4.2.1 使用new和delete4.2.2 使用智能指针4. 总结 1. 内存4区 程序在运行时,指令是存放在内存中的,程序大致占用了内存大概4个区: 代码区、数据区、栈区、堆区 ...
  • 1.局部变量的指针和局部指针变量是两个不同概念 2.局部变量在函数体结束后生命期也结束,它的指针(即它的地址)是无效变量的地址,所以函数不能返回这种地址值 3,局部指针变量在函数结束后生命期也结束,但它...
  • 子函数运行结束时,所有局部变量的内存单元会被系统释放。形参和函数内部的局部变量的生命期和作用域都是在函数内部( static变量的生命期除外)。 在C中,函数被调用时的传参方式有两种形式:传值和传址。 ...
  • C语言指针与函数

    2019-02-25 20:21:01
    C语言指针与函数 前言 指针的重要应用场景是作为函数的参数以及函数的返回值。那么我们就需要有一下三个问题: 1、如何使用指针作为函数参数; 2、如何定义和使用返回值为指针的函数; 3、如何定义和使用指向...
  • c:局部变量不释放所指向内存空间

    千次阅读 2016-09-22 14:19:34
    局部变量在函数返回时就 会释放, 但是在指针变量这个问题上, 这表示指针释放, 而 不是它所指向的对象。 用 malloc() 分配的内存直到你明确释放它之前都会保留 在那里。 一般地, 对于每一个 malloc() 都必须有个...
  • 函数返回局部指针变量是否可行

    千次阅读 2018-08-18 11:25:45
    近期在准备面试的过程中,多次遇到了strcpy的实现问题,在很多实现程序中...我们大家都知道指针函数的返回指针不能指向函数内的自动变量,如果需要返回函数的内部变量的话,就需要将该变量声明为静态变量。为什么函...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 94,974
精华内容 37,989
关键字:

c局部指针需要释放吗