被忽略的C语言堆栈内存编程细节

没想到,评论区的一个提问,成了我知识的裂缝。🤣
前段时间解决了自己代码中的一个关于栈内存问题,便班门弄斧的写了一篇文章栈内存文章,没想到发出来很快便被大佬发现了其中一个问题🤣,在评论区里和大佬开始了你问我答环节,直到最后大佬问了我一个问题,“什么叫C语言栈的自动销毁?何来自动?何为销毁”,我才发现自己学习的太浅薄了,便想搞清楚其中的原理🧐。
image.png

什么是堆栈?

堆栈是一种特殊的数据结构,它遵循先进后出(LIFO,last in first out)原则,这意味着最后放入的堆栈的元素会最先被取出,堆栈用于多种场景,如函数调用,算法实现等。
image.png

让我们用一个生活中的例子来理解堆栈:

想象你有一叠盘子。当你清洗盘子并将它们堆放起来时,你通常会将洗净的盘子放在最上面,然后,当你需要使用盘子的时候,你会从最上面的那个,即最后放上去的那个,这就是堆栈的工作方式:最后放上去的盘子总是第一个被使用,而最后放上去的盘子则留在堆栈的底部。
veer-147101848.jpg
在编程中,堆栈的一个常见用途是存储函数调用时的局部变量和返回地址。当第一个函数被调用时,它的信息(如参数和局部变量)会被“压入”堆栈。当函数执行完毕并返回时,这些信息会被“弹出”堆栈,以便下一个函数调用可以使用堆栈空间。

如何自动的,如何销毁退栈的内存空间?

自动”意味着这一过程不需要程序员的干预,它是在函数返回时由系统自行完成的。当一个函数被调用时,它的局部变量会被推入栈中,这些变量只在函数执行期间存在。一旦函数执行完毕并返回,这些局部变量就不再需要了,因此它们占用的内存会被清理,这就是所谓的“销毁”。
32DAF507.gif
在计算机操作系统的底层,程序的内存空间管理是一个自动化的过程。当一个函数调用发生时,操作系统会为该函数的局部变量和其他相关信息在栈上分配内存。这些信息包括函数的参数、返回地址以及局部变量,这个过程称为“入栈”。
当函数执行完毕后,需要将这些局部变量和信息“出栈”,即释放这部分内存,这是通过如下步骤实现的:

  1. 函数返回:当函数完成其任务后,它会准备返回到调用它的地方。这时,CPU会读取之前保存的返回地址,并将控制权交回给调用者。
  2. 栈指针移动:栈指针(通常是CPU中的一个寄存器)会向上移动,跳过这个函数为局部变量分配的内存区域。这个动作实际上“丢弃”了这些局部变量。
  3. 内存释放:虽然栈指针移动了,但实际上内存并没有被清理或擦除。它知识被标记为可用,等待下一次函数调用时重写。
  4. 操作系统的角色:在整个过程中,操作系统负载管理栈的大小和限制。如果一个程序尝试使用超出其分配的栈空间,操作系统会介入并可能终止该程序,这通常称为栈溢出。

这个过程是由编译器和操作系统自动管理的,不需要程序员进行任何手动干预。这就是为什么我们说栈内存是自动分配和销毁的。在程序结束后,操作系统会回收所有内存,包括堆和栈空间。这意味着即使程序员没有显式的释放堆上的内存,操作系统在程序终止时也会确保这些资源得到清理。

C语言退出函数栈的时候,自动销毁的底层的原理是什么?

32DB1541.jpg
C语言函数栈帧是函数调用过程中在内存的栈区上开辟的一块空间,用来存放函数的参数、返回值、局部变量和上下文信息。函数栈帧由两个寄存器esp和ebp维护,esp指向栈顶,ebp指向栈底。当一个函数被调用时,会发生以下步骤:

  1. 栈帧的创建:
  • push ebp:将当前函数的基指针(ebp)压入栈中,保存上一个栈帧的基指针。
  • move ebp, esp:将栈顶指针(esp)的值复制到基指针(ebp),这样ebp就执行当前栈帧的开始位置。
  • sub esp, size:通过减少esp的值,为局部变量分配空间。
  1. 函数执行:函数的局部变量和参数在栈帧中被访问和修改。
  2. 栈帧的销毁:
  • move esp, ebp:在函数结束前,将ebp的值复制回esp,这样esp指向了当前栈帧的开始位置,即销毁了对局部变量的分配。
  • pop ebp:弹出之前保存的旧ebp值,恢复上一个栈帧的基指针。
  1. 返回地址:
  • ret:从栈中弹出返回地址并跳转回调用者的代码中继续执行。

这个过程是由编译器自动完成的。编译器回在编译时生成相应的汇编指令来管理栈帧的创建和销毁。当函数返回时,通过移动栈顶指针(esp)来“销毁”局部变量,实际上是将它们占用的内存标记为可用,而不是物理上的清除。这样,下一次函数调用时,新的局部变量就可以重用这部分内存。
这种自动化的内存管理机制使得程序员无需手动管理每个函数的存储释放,简化了编程工作并防止了内存泄漏。
32D2E667.jpg
当我再次面对那个问题时,我已经不再是原来的我。我学会了,在编程的世界里,每一次的深入都是一次全新的蜕变。感谢那位大佬,让我知道了,学习,永远不应该止步。在代码的海洋里,还有无数的奥秘等待我去揭开。🚀

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/598557.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

程序员的神器指南!揭秘软件开发必备工具

在软件开发的广袤海洋中,程序员们像是驾驶着帆船探索未知的航海者。他们面对的不仅仅是代码的挑战,还有项目管理、协作沟通和时间限制的压力。为了应对这些挑战,程序员们需要一系列强大的工具,就像是海中的指南针,帮助…

项目又延期了,怎么办?

Ada问:负责的几个版本上线都延期了,在测试环境出了问题,改过再测上线后,还是出问题。身为产品经理,很困惑,项目不断延期,又被打脸。怎么办? 学姐回答: 经理每天都是忙着…

mac安装linux的centos strem9 虚拟机解压rar文件报错

背景:解压rar文件需要再linux上安装unrar工具 yum install unrar直接安装的后解压报错,如图 解决办法: 下载:wget https://www.rarlab.com/rar/rarlinux-x64-6.0.2.tar.gz 安装: tar -zxvf rarlinux-x64-6.0.2.tar.gz cd rar …

C语言例题35、反向输出字符串(指针方式),例如:输入abcde,输出edcba

#include <stdio.h>void reverse(char *p) {int len 0;while (*p ! \0) { //取得字符串长度p;len;}while (len > 0) { //反向打印到终端printf("%c", *--p);len--;} }int main() {char s[255];printf("请输入一个字符串&#xff1a;");gets(s)…

redis持久化存储

Redis的持久化机制 Redis是一个基于内存的数据库&#xff0c;它的数据是存放在内存中&#xff0c;内存有个问题就是关闭服务或者断电会丢失。Redis的数据也支持写到硬盘中&#xff0c;这个过程就叫做持久化。 Redis提供如下两种持久化方式 RDB&#xff08;Redis DataBase&am…

外网禅道配置

exportfs -avrf 修改代码&#xff0c;避免启动太慢&#xff1a;vi /opt/zbox/bin/zbox.php 启动和停止 /opt/zbox/zbox start /opt/zbox/zbox stop

如何保护数据安全?迅软DSE加密系统给信息撑把保护伞!

信息安全当然需要保护&#xff0c;不然企业的信息可以发给任何人&#xff0c;普通信息还好&#xff0c;如果是重要机密呢&#xff0c;企业重要信息被发出去后可能会造成一些麻烦&#xff0c;所以可以使用加密系统&#xff0c;对数据进行安全保护&#xff0c;防止泄密问题&#…

一次 K8s Pod 频繁被“驱逐”,结果竟是这样的?

问题描述 某天下午运维反馈说我们这一个pod一天重启了8次&#xff0c;需要排查下原因。一看 Kibana 日志&#xff0c;jvm 没有抛出过任何错误&#xff0c;服务就直接重启了。显然是进程被直接杀了&#xff0c;初步判断是 pod 达到内存上限被 K8s oomkill 了。 Containers: c…

学习软考----数据库系统工程师22

关系运算 基本的关系代数运算 拓展的关系运算 除&#xff1a;需要S连接中属性为C和D的两个元组都与R连接一样&#xff0c;且在R连接中对应的另外的元素完全一致 总结

VBA在Excel中注册登录界面的应用

Excel工作表也可以做一个小程序,登录注册后可以访问或修改。为了简便,没有做复杂的控件,能说明问题就行。可以根据需要添加更多的判断条件,控制注册和访问人数。本次操作对注册没有任何限制,只要注册后就可以根据注册的账号和密码进行访问和修改。注册登录界面截图: 操作…

【数据结构】 顺序表专题

目录 1.顺序表的概念及结构 1.1线性表 1.2顺序表 2.顺序表的分类 2.1静态顺序表 2.2动态顺序表 1.顺序表的概念及结构 1.1线性表 线性表&#xff08;Linear List&#xff09;是数据结构中的一种基本结构&#xff0c;它是一个具有n个数据元素的有限序列。线性表的特点是数…

速卖通新卖家测评攻略:从入门到精通

在电商行业中&#xff0c;测评被广泛认为是提升产品转化率和销量的有效手段。对于速卖通的卖家而言&#xff0c;测评的必要性更是显而易见。测评&#xff0c;本质上与国内电商的补单行为相似&#xff0c;是一种通过增加销量来提升产品权重的方法。 特别是在竞争激烈的类目中&a…

Colibri for Mac v2.2.0 原生无损音频播放器 激活版

Colibri支持所有流行的无损和有损音频格式的完美清晰的比特完美播放&#xff0c;仅使用微小的计算能力&#xff0c;并提供干净和直观的用户体验。 Colibri在播放音乐时使用极少的计算能力。该应用程序使用最先进的Swift 3编程语言构建&#xff0c;BASS音频引擎作为机器代码捆绑…

VS code ESP-IDF 提示“loading ‘build.ninja‘: 系统找不到指定的文件” 的解决方案

最近在搞esp32&#xff0c;使用VS code进行开发&#xff0c;但是当把别人的工程直接导进去的时候编译报错找不到文件&#xff1a; 但是在之前明明已经新建工程成功了&#xff0c;那应该是缺少某些文件吧。在网上找到一种方法就是将文件拷贝到之前新建的文件里面&#xff0c;确…

Wish、Newegg、Allegro卖家如何做测评补单 快速提升产品权重与销量

大部分主流平台卖家都会使用测评补单来增加产品权重、提高销量。经常会有一些平台的卖家咨询我其他平台能否像亚马逊一样通过测评补单来提升曝光。 其实大部分跨境电商都是可以通过补单来增加店铺权重提升产品排名。其实亚马逊相对来说风控是最严的&#xff0c;风控点多达几十…

WouoUIPagePC端实现

WouoUIPagePC端实现 WouoUIPage是一个与硬件平台无关&#xff0c;纯C语言的UI库&#xff08;目前只能应用于128*64的单色OLED屏幕上&#xff0c;后期会改进&#xff0c;支持更多尺寸&#xff09;。因此&#xff0c;我们可以在PC上实现它&#xff0c;本文就以在PC上使用 VScode…

网络安全之动态路由RIP详解

RIP&#xff1a;路由信息协议 RIP分为三个版本&#xff1a;RIPV1,RIPV2&#xff08;在IPv4中使用&#xff09;,RIPNG&#xff08;在IPv6中使用&#xff09; RIPV1是一种有类别的距离矢量型路由协议&#xff08;不传递网络掩码&#xff09;。 RIPV2是一种无类别的距离矢量型路…

Java代码基础算法练习-删除有序数组中的重复项-2024.05.07

任务描述&#xff1a; 给一个有序数组&#xff08;共10个元素&#xff09;&#xff0c;请在不新建数组的情况下&#xff0c;删除重复出现的元素&#xff0c;使 每个元素只出现一次&#xff0c;最后请输出删除重复元素后数组的新长度和数组元素。 解决思路&#xff1a; 要删除…

javascript中的DOM和BOM

目录 JavaScript中的对象 简介&#xff1a; js对象的基本用法&#xff1a; 创建对象&#xff1a; 访问对象的属性&#xff1a; 设置修改对象的属性&#xff1a; 删除对象的属性&#xff1a; DOM&#xff08;文档对象模型&#xff09; 简介&#xff1a; DOM对象的属性…

【毕业设计】基于微信小程序的校园快递平台系统设计与实现

1.项目介绍 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统校园快递平台系统信息管理难度大&#xff0c;容错率…
最新文章