0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C语言使用函数调用在内存中究竟发生了什么?

硬件攻城狮 来源:混说Linux 2023-01-13 14:09 次阅读

C语言使用函数调用,我们再熟悉不过了,但是函数调用在内存中究竟发生了什么真的清楚吗?只有搞清楚内存里的内幕,才算完全搞懂函数的调用。

这里涉及一个知识点:栈。不管是函数执行还是函数调用,一定要开辟一段内存空间,这块空间就是

栈是一种“后进先出(FILO)”的逻辑结构,比如一堆碗,最先洗完的碗放在最下面,最后洗完的在最上面,吃饭的时候从最上面开始拿。

最上面的碗我们称之为栈顶,最底下的碗我们称之为栈底,在内存中栈顶是低地址,栈底是高地址。

这里我们可以发现,根据碗的堆叠顺序知道栈是从高地址往低地址分配内存的,与其它的内存地址从低到高分配内存有所不同。

e4d971f2-92f6-11ed-bfe3-dac502259ad0.jpg

栈内存的大小由函数定义的局部变量的具体情况而定,另外,一个程序里的所有函数的栈内存在逻辑上是连在一起的,比如a函数分配了一段栈内存,此时a函数又调用了b函数,那么b函数的栈内存会接着在a函数栈内存之后去分配,依次类推。

废话不多说,来看一张函数调用的图:

e4e57d1c-92f6-11ed-bfe3-dac502259ad0.png

main函数运行时,系统会为main函数分配一个栈帧,用来存放main函数中定义的局部变量(还有其他数据,此处略过不计)。

总结几点比较重要的:

一、栈在函数调用中起着非常重要的作用:

向被调用函数传递参数,参数从右往左依次push到栈中;

保存函数的非静态局部变量;

返回函数的返回值

保存上下文的环境,保留之前的数据,比如:返回地址、寄存器的值等,这些值会被存到栈中。

二、每个函数的栈帧都是独立存在的,里面的局部变量也是相对独立的,当执行调用fun1函数时,系统又会马上给fun1函数分配一个栈帧,其中main里面的x、y和fun1里面的a、b,它们各自在不同的内存空间。

e4f219aa-92f6-11ed-bfe3-dac502259ad0.png

注意,执行fun1函数的时候,main函数并没有退出,它的栈帧也没有消失,fun1函数的栈帧是堆叠在main函数的栈帧下面的,如果fun1函数还调用了其它函数,那么栈内存就继续向下增长。

三、栈内存它是临时性的,相应函数的退出(比如fun1函数执行完return返回c 之后),栈帧就会被释放,也就是这块栈空间被释放(系统回收),然后随着逐个函数的退出,栈空间也逐个从下往上退出

e4fc2472-92f6-11ed-bfe3-dac502259ad0.png

四、一个程序的栈是由若干段函数的栈帧组成的,栈帧的长度取决于对应函数的局部变量的个数和类型,因此,在开发的时候,我们应尽量不要定义太大、太多的局部变量,占用内存太大的数据考虑使用堆内存。

最后,如果搞懂了函数调用背后的原理(当然其实还有很多细节),遇到问题的时候才能做到从容不迫。





审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言
    +关注

    关注

    180

    文章

    7597

    浏览量

    136120

原文标题:你真的知道C语言函数调用的内幕吗?

文章出处:【微信号:mcu168,微信公众号:硬件攻城狮】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    C语言函数调用过程中内存变化解析

    相信很多编程新手村的同学们都会有一个疑问:C 语言如何调用函数的呢?局部变量的作用域为什么仅限于函数内?这个
    的头像 发表于 12-11 16:21 3724次阅读

    C语言使用函数调用的知识点

    C语言使用函数调用,我们再熟悉不过了,但是函数调用在内存
    发表于 09-07 11:47 806次阅读

    C语言内存知识总结:memset函数和calloc函数

    memset(翻译:清零)是计算机C/C++语言初始化函数。作用是将某一块内存
    发表于 10-24 10:40 1090次阅读

    小数在内存是如何存储的?为什么C语言中的浮点数不支持位移操作?

    小数在内存是如何存储的?为什么C语言中的浮点数不支持位移操作?
    发表于 08-16 09:24 1005次阅读
    小数<b class='flag-5'>在内存</b><b class='flag-5'>中</b>是如何存储的?为什么<b class='flag-5'>C</b><b class='flag-5'>语言</b>中的浮点数不支持位移操作?

    C++教程之函数的递归调用

    C++教程之函数的递归调用 在执行函数 f 的过程,又要调用 f
    发表于 05-15 18:00 35次下载

    C语言回调函数学习

    对指针的应用是C语言编程的精髓所在,而回调函数就是C语言里面对函数指针的高级应用。简而言之,回调
    发表于 05-27 09:44 7193次阅读

    系统调用函数库分析及实例

    作为用户我们极少接触系统调用,但是我们熟悉C 语言,对库函数调用并不陌生。C
    发表于 06-23 16:46 46次下载
    系统<b class='flag-5'>调用</b><b class='flag-5'>函数</b>库分析及实例

    C语言程序设计的一些教学思维说明

    体现为函数内部的语句在 EIP 寄存器加法操作支持下顺序自动地执行以及函数之间的调用在内存堆栈区支持下自动地进行跳转。最后,针对计算思维的抽象和自动化特征,给出了 C
    发表于 10-15 08:00 14次下载
    <b class='flag-5'>C</b><b class='flag-5'>语言</b>程序设计的一些教学思维说明

    C语言代码调用汇编函数需要注意什么

    来看下混合语言工程,就比如在汇编程序调用C函数,或者在C
    的头像 发表于 11-12 11:04 2791次阅读

    C语言-函数的定义、声明、传参

    C语言函数是非常重要的知识点,一个完整的C语言程序就是由主函数和各个子
    的头像 发表于 08-14 09:57 1898次阅读

    C语言中数组在内存如何表示

    C语言中数组在内存是怎样表示的,今天就给大家聊聊这个话题。
    的头像 发表于 02-15 14:35 894次阅读
    <b class='flag-5'>C</b><b class='flag-5'>语言</b>中数组<b class='flag-5'>在内存</b><b class='flag-5'>中</b>如何表示

    C语言函数调用的形式及过程

    C语言函数调用时的数据传递 在调用有参函数时,主调函数
    的头像 发表于 03-10 14:28 1605次阅读

    调用sleep时操作系统中发生什么了

    相信不管你使用的是什么语言,或多或少都会调用过sleep函数,那么你知道当调用这个函数时操作系统中发生了
    的头像 发表于 03-31 10:47 975次阅读
    <b class='flag-5'>调用</b>sleep时操作系统中<b class='flag-5'>发生</b>什么了

    什么是函数调用

    函数调用,就是使用我们已经定义好的函数,或者C语言自带的库函数
    的头像 发表于 04-04 17:21 5642次阅读

    C语言内存泄漏问题原理

    内存泄漏问题只有在使用堆内存的时候才会出现,栈内存不存在内存泄漏问题,因为栈内存会自动分配和释放。C
    发表于 03-19 11:38 477次阅读
    <b class='flag-5'>C</b><b class='flag-5'>语言</b><b class='flag-5'>内存</b>泄漏问题原理