初学者关于c语言中函数局部变量空间释放的理解

初学者关于c语言中函数局部变量空间释放的理解

2017年04月30日 10:17:05

阅读数:1063

比如下面一段代码:

 

 
  1. #include <stdio.h>

  2.  
  3. int* fun();

  4.  
  5. int* fun(){

  6. int a;

  7.  
  8. a = 1;

  9. return &a;

  10. }

  11.  
  12. int main(){

  13. int *p = NULL;

  14.  
  15. p = fun();

  16. *p = 2;

  17.  
  18. printf("%d\n", *p);

  19.  
  20. return 0;

  21. }

 

理论上来说,a是fun()函数的局部变量,而局部变量的内存空间应该在该函数运行结束后即释放掉,也就是说a变量的空间应该在fun()函数运行结束后即释放掉,所以在主函数用用p来接收a的首地址是没有意义的,因为p将指向了一个已经被释放掉了的空间,将会出现非法内存访问,但运行结果却如下:

888

999

没有错误,也没有警告。

 

这个问题在初学c语言的时间困惑了我很长的时间,直到我学习了数据结构,学到系统堆栈那一部分才得到了解答。

 

函数调用过程中,一个函数在调用另外一个函数的时候,会先将调用前的现场信息保存在系统堆栈中,然后按照从又向左的顺序(c语言)将实参的结果入栈,而被调用的函数的形参,用的就是实参的空间,当被调用的函数运行结束后,局部变量的空间被“释放”的本质,其实是栈顶的指针,移动到了调用前函数的现场信息的地方,所以刚才被调用的函数的局部变量,实际上它的值还是存放在内存中,并且在当前栈顶指针的上面的连续空间中。

 

这样就可以解释为什么刚才的程序中为什么不会出现错误,也不会出现非法内存访问的情况。

 

但是,这样做是很危险的,比如调用一个函数之后,又进行了函数的调用,则另一个函数的局部变量等信息,也会从堆栈中当前函数现场信息的位置向上累加,会覆盖第一次调用的局部变量所占有的空间。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值