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


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


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://i-blog.csdnimg.cn/blog_migrate/81a917739a8bd8e1de07c92e3ec6f6b6.png

5.总结

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

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

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

  • 14
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值