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

    文章

    7533

    浏览量

    128785

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

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

收藏 人收藏

    评论

    相关推荐

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

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

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

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

    在LabVIEW调用C语言——调用函数节点

    在LabVIEW调用C语言——调用函数节点学习LabVIEW也有一段时间了,从
    发表于 04-20 09:14

    求助,有关调用DLL,错误1097发生于vi调用函数节点

    错误1097发生于 vi调用函数节点可能原因LabVIEW:调用函数节点
    发表于 11-14 13:50

    C语言函数是什么?

    地开发特定平台的应用程序。比如作为Windows应用程序的开发者,应尽量熟悉Windows SDK;作为Linux应用程序开发者,应尽量熟悉Linux系统调用和POSIX函数规范。  学习C
    发表于 01-07 18:05

    C语言函数如何调用

    C语言函数如何调用
    发表于 10-18 09:06

    各种变量在内存的位置有何不同

    各种变量在内存的位置有何不同?怎样使用交叉变压器将转换语言分类的翻译呢?
    发表于 10-22 09:33

    陷阱:中断中分配内存

    多。从C迁移到C++又向前迈进了一步。抽象级别更高,程序源代码变得更加紧凑。与此同时,目标系统究竟发生了什么变得更加不清楚。在许多情况下,
    发表于 11-23 10:58

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

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

    C语言程序的动态内存中栈内存区域的概念

    C语言程序的动态内存分为栈内存区域和堆内存区域两种。栈内存是由编译器管理的,而堆内存是由程序
    的头像 发表于 06-29 10:34 1638次阅读

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

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

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

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

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

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

    什么是函数调用

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

    C语言内存泄漏问题原理

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