当前位置: 首页 > news >正文

C 语言-内存管理

📑 文章目录

  • 一、C 程序内存两大分配体系划分
  • 二、程序整体内存四大分区(程序加载进内存后固定布局)
  • 三、栈内存运行核心规则
  • 四、堆内存:动态内存接口与底层逻辑
  • 五、高频内存错误产生逻辑(由内存分区特性直接决定)
  • 六、各区域生命周期汇总
  • 七、文章补充说明

本文结合 C 语言标准规范,针对单片机、Linux 应用层 C 开发人员,拆解程序运行时五大内存分区基础逻辑,梳理堆、栈、全局区的分配释放规则、函数调用栈运作机制、malloc/free 底层行为,以及内存错误高发场景成因。

一、C 程序内存两大分配体系划分

编译期静态内存分配:编译器在链接阶段就划定内存空间大小,程序运行期间地址、容量固定,无需手动释放。包含只读常量区、全局数据区、静态变量区。

运行期动态内存分配:程序执行过程中主动向操作系统申请内存,由开发者手动管控生命周期,也就是堆内存。搭配函数自动使用的栈内存,构成程序动态运行的内存载体。

二、程序整体内存四大分区(程序加载进内存后固定布局)

程序被操作系统载入内存后,整体分为 4 个区域,从上至下地址分布依次为:

代码段:存放编译后的二进制机器指令、函数实体代码。权限只读,运行中不可修改,字符串常量也寄存于此,程序全程不会被释放。

全局区:放全局变量,静态变量
data 段:初始化的全局变量、初始化 static 静态变量,程序启动时分配,进程销毁才回收;
bss 段:未初始化全局变量、未初始化 static 变量,系统默认填充 0,只占用编译符号表空间,运行时一次性清零分配。

栈区 :系统自动管理内存

函数调用专属内存空间,由 CPU 栈指针寄存器自动分配、函数执行结束自动回收。存放局部普通变量、函数形参、函数返回地址、临时寄存器数据、函数调用现场。栈大小由系统预先设置,容量固定。

堆区:开发者手动管理内存

位于 bss 段与栈中间,地址向上增长。依靠 malloc、calloc、realloc 申请内存,free 主动释放。堆没有固定大小,受系统可用物理内存限制,生命周期完全由代码控制。

三、栈内存运行核心规则

1、栈帧运作机制

每一次函数调用都会生成独立栈帧,函数入栈开辟空间,函数执行完毕栈帧自动出栈销毁,局部变量随之失效。

2、栈核心特性

分配释放自动完成,无需人为操作,执行效率极高;
空间容量受限,递归深度过大、局部数组过长极易造成栈溢出;
栈内存数据随机脏值,局部变量不初始化会携带随机数据。

3、典型使用场景

函数内部临时变量、数组、结构体临时数据、函数参数传递、函数跳转现场保存。

四、堆内存:动态内存接口与底层逻辑

1、四个核心 API 功能

malloc (n):申请 n 字节原始内存,内存保留原有脏数据,不会清零;
calloc (num, size):分配 num 个 size 大小内存块,分配完成自动清零整块内存;
realloc (ptr, new_size):扩容 / 缩容已有堆内存,大概率会更换内存物理地址;
free (ptr):释放已申请的堆内存,释放后指针变为野指针。
(使用时需包含 mclloc.h / stdlib.h 头文件)

2、堆内存分配与释放约束

申请和释放必须一一对应,单次 malloc 仅允许执行一次 free,重复 free 直接引发程序崩溃;
(为了解决这个问题通常会将NULL赋值到已释放内存的指针来防止程序崩溃)
free 只回收内存使用权交还给操作系统,不会清空原有内存数据;
堆内存地址由操作系统分配,地址不连续,存在内存碎片问题。

五、高频内存错误产生逻辑(由内存分区特性直接决定)

栈溢出:局部超大数组、无限递归,超出系统栈预设容量,程序异常崩溃;
野指针 / 悬空指针:栈局部变量地址返回上层函数、堆内存 free 之后继续使用原指针;
内存泄漏:malloc 申请堆内存,程序退出前没有执行 free,长时间运行导致内存占用持续走高;
数组越界访问:读写超出数组开辟的内存范围,篡改相邻内存数据,出现随机性 bug;
修改只读区数据:修改字符串字面量、const 全局常量,触发操作系统内存保护报错。

六、各区域生命周期汇总

代码段、只读段、全局静态区:进程运行全程有效,进程结束由系统统一回收;
栈内存:随函数调用创建,函数返回立刻自动销毁;
堆内存:从 malloc 申请开始生效,调用 free 主动释放,进程退出系统强制回收所有堆内存。

七、文章补充说明

本篇为 C 语言内存管理基础篇章,只讲解分区划分、基础特性、接口规则。

http://www.jsqmd.com/news/1288063/

相关文章:

  • 磨削加工如何正确选择适合的高精度过滤方式
  • 2026南安市瓷砖空鼓怎么处理?地砖墙砖松动微创注浆修复方案|本地家装修缮科普 - 宅安选房屋修缮
  • Litestar 4D:室内照明
  • 计算机毕业设计之正文视频弹幕数据挖掘分析
  • BilibiliDown:解锁B站视频下载的终极解决方案
  • 从代码注释到可视化图表:如何用VSCode Mermaid Preview提升技术文档效率
  • 提示词优化进入“毫米级调优”时代:用Token级注意力热力图定位偏差源,3小时完成传统7天迭代周期
  • 基于CNN与MATLAB GUI的人脸表情识别系统开发
  • Obsidian插件汉化宝典:3分钟让英文插件变中文的零代码秘籍
  • Ryujinx:高性能Nintendo Switch模拟器的架构解析与实践指南
  • 如何在普通PC上安装macOS:黑苹果完整指南与实用工具集
  • XLeRobot终极指南:如何用660美元打造你的家庭机器人并实现强化学习训练
  • Agent 的记忆,记岔了比没记更坑
  • 宣城2026.7月新推荐:专业正规防水补漏公司全场景免砸砖 - 超人防水
  • 预算10-14万在酒泉做整装,闭口合同真能锁死价格不增项?
  • Diablo Edit2:终极暗黑破坏神2角色编辑器免费体验指南
  • 【App Store审核通过率92.7%的AI图标生成方案】:融合Figma+Stable Diffusion+人工微调的黄金三角模型
  • Zig 增量编译:毫秒级重建复杂应用,开发效率大提升!
  • VMware Unlocker 4.2.9终极指南:在普通PC上轻松运行macOS虚拟机的完整教程
  • Seata AT 模式不用写回滚代码:一次“脏写“让我们重读了 undo_log 的插入时机
  • Python类变量与实例变量详解:命名空间、查找链与实战避坑指南
  • Honey Select 2终极增强指南:10分钟打造完美游戏体验的完整解决方案
  • UML建模与面向对象分析
  • 如何在5分钟内为Microsoft Word安装免费的APA第七版引用样式
  • 基于MATLAB和PYTHON的跨平台光学建模与设计
  • 5分钟掌握HunterPie:《怪物猎人:世界》游戏数据监控插件终极指南
  • 北京geo优化公司哪家服务好?广拓时代解析数据复盘能力
  • 扣子定时任务设置全攻略:从零到上线的7个关键步骤,90%开发者都踩过的3个坑
  • GoBruteforcer僵尸网络攻击分析与Linux服务器防护
  • 子域名挖掘全攻略:从被动收集到主动枚举的完整安全评估流程