C语言中指针局部变量释放问题

C语言基础 专栏收录该内容
2 篇文章 0 订阅


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


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.总结

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

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

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

  • 9
    点赞
  • 2
    评论
  • 15
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:技术黑板 设计师:CSDN官方博客 返回首页

打赏作者

O不落雨O

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值