zoukankan      html  css  js  c++  java
  • C语言函数返回指针的问题

    自我们开始学习C语言中的指针,老师就说返回函数局部变量的地址是没有意义的,因为函数调用完毕,系统回收函数中用到各种资源,函数栈顶指针向高位地址移动。指针指向的内容已经被释放,返回的指针会指向不可预料的内容。

    我们可以从C程序的内存布局讲起(详细内容,请查看超链接内容,本片文章只会讲解与本篇文章相关的内容)。

     

     

     C语言的内存布局具体可以分为五部分:

    1. 栈(stack):是一个先进后出的数据结构,和函数调用相关(函数中的局部变量存储在该部分),栈是由高地址向低地址增长(向下增长),栈的底部存放着命令行参数和环境变量。
      • 我们可以这样简单的理解C程序执行过程,main(int argc, char *argv)函数先入栈,栈顶指针下移,遇到其他函数调用,该函数进栈,栈顶指针下移,直到再也没有其他函数调用时,函数返回,栈顶指针上移,并且释放被调函数所占用的资源(包括局部变量),直到main(int argc, char *argv) 返回,程序执行完毕,操作系统回收资源。
    2. 堆(heap):是用户自己管理的内存部分,可以通过 malloc()、realloc()和 free()进行管理。堆是从低地址向高地址增长。
      • 申请的内存空间一定要释放,否则会造成内存泄漏。
      • 用户自己申请的内存空间在free之前都会一直存在。(所以函数可以返回自己在堆上申请的内存地址)
    3. Uninitialized Data Segment:用于存放用户未初始化的全局变量和静态局部变量。(但是编译器会默认全部初始化为0)
    4.  Initialized Data Segment:用于存放用户已经初始化的全局变量和静态局部变量
    5. 程序代码区(Text):用来存放可执行代码。

    那么函数可以返回哪些变量的指针呢?

    1. 存储在 Uninitialized Date Segment 和 Initialized Data Segment都具有静态存储周期,即在程序执行期间一直存在。所以函数可以返回全局变量和静态局部变量的指针;
    2. 函数可以返回自己在堆上动态分配的内存的地址,只要这块内存未被free()释放即可。

    还有一种特殊情况:

      函数的参数本身就是指针变量,函数最后返回了参数,由于参数是由主调函数完成初始化,并且函数返回值指向主调函数的一个变量,所以不会产生问题。

    (如有错误,欢迎指正!)

    种一棵树最好的时间是十年前,其次是现在。
  • 相关阅读:
    Matlab 绘制三维立体图(以地质异常体为例)
    Azure DevOps的variable group实现array和hashtable参数的传递
    Azure DevOps 利用rest api设置variable group
    Azure AADSTS7000215 其中一种问题的解决
    Power BI 实现实时更新Streaming Dataset
    AAD Service Principal获取azure user list (Microsoft Graph API)
    Matlab 沿三维任意方向切割CT图的仿真计算
    Azure Powershell script检测登陆并部署ARM Template
    Azure KeyVault设置策略和自动化添加secrets键值对
    Azure登陆的两种常见方式(user 和 service principal登陆)
  • 原文地址:https://www.cnblogs.com/HyattXia/p/12823484.html
Copyright © 2011-2022 走看看