跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++

嵌入式 C/C++ 核心考点:内存管理、多态与系统调用

深入探讨嵌入式开发中 C/C++ 的关键机制,涵盖全局与静态变量的存储差异、析构函数虚化对防止内存泄漏的重要性、重载与覆盖的本质区别。同时解析 select 文件描述符轮询机制及 fork/exec/wait 进程控制流程,为底层开发与调试提供理论支撑。重点在于理解内存布局、多态实现原理及系统调用开销。

并发大师发布于 2026/3/16更新于 2026/9/946 浏览
嵌入式 C/C++ 核心考点:内存管理、多态与系统调用

嵌入式 C/C++ 核心考点:内存管理、多态与系统调用

在嵌入式开发中,对底层机制的理解往往决定了系统的稳定性。今天我们来梳理几个高频出现的 C/C++ 知识点,涵盖变量存储、面向对象特性以及进程控制,希望能帮你把基础打得更牢。

一、变量与内存管理

全局变量和静态变量的区别

很多初学者容易混淆这两者,其实核心差异在于作用域和生命周期。

  1. 作用域:全局变量对整个程序可见,而局部变量仅限于当前函数或代码块内。
  2. 存储位置:全局变量(包括静态全局和静态局部)分配在全局数据区(静态存储空间),而普通局部变量通常分配在栈区。
  3. 生命周期:全局变量随程序启动创建,随程序结束销毁;局部变量则随着函数调用入栈而出栈,存在时间较短。
  4. 使用方式:全局变量可在程序各部分共享,局部变量只能在定义它的范围内访问。

全局变量能否定义在头文件中?

可以,但要注意规则。如果在多个 .c 文件中包含同一个头文件,且都在其中声明了同名全局变量,链接时会报错。正确的做法是:在头文件中声明 extern,或者在其中一个 .c 文件中定义并赋初值,其他文件通过 extern 引用。如果都定义为 static,则每个文件都有独立的副本,不会冲突,但这通常不是我们想要的效果。

局部变量能否和全局变量重名?

能。当局部变量与全局变量同名时,局部变量会屏蔽全局变量。在函数内部引用该名字时,编译器优先匹配局部变量。有些编译器甚至允许在同一个函数的不同循环体内定义同名的局部变量,它们的作用域仅限于各自的循环体。

二、C++ 面向对象特性

为什么析构函数必须是虚函数?

这是为了防止内存泄漏。当你通过基类指针指向一个派生类对象并删除它时,如果基类的析构函数不是虚函数,只会调用基类的析构函数,导致派生类特有的资源没有被释放。将其设为虚函数后,动态绑定机制会确保调用到正确的派生类析构函数。

为什么 C++ 默认析构函数不是虚函数?

因为虚函数需要维护虚函数表(vtable)和虚表指针(vptr),这会占用额外的内存空间。对于不会被继承的类来说,开启虚函数机制纯属浪费。因此,只有当类被设计为基类且可能通过基类指针操作子类时,才需要显式声明虚析构函数。

重载和覆盖有什么区别?

  • 关系维度:覆盖发生在父子类之间(垂直关系),重载发生在同一个类中(水平关系)。
  • 数量限制:覆盖是一对一的关系,重载则是多个方法之间的关系。
  • 决定因素:覆盖取决于对象的实际类型(运行时决定),重载取决于参数列表(编译时决定)。

虚函数表如何实现运行时多态?

简单来说,每个包含虚函数的类都有一个虚函数表,存放着虚函数的地址。对象实例中包含一个指向该表的指针。当子类重写父类虚函数时,表中对应位置的地址会被更新。这样,通过基类指针调用虚函数时,程序会根据对象实际的虚表指针找到子类的实现,从而实现多态。

三、系统编程基础

C 语言函数调用的底层原理

大多数 CPU 使用栈来支持函数调用。每次调用都会创建一个栈帧(Stack Frame),用于传递参数、保存返回地址、临时寄存器和局部变量。栈帧由帧指针(如 ebp)和栈指针(如 esp)界定。帧指针指向栈帧头部,栈指针指向栈顶。这种机制保证了函数调用的嵌套和上下文切换能够有序进行。

函数调用栈结构

select 函数详解

select 是多路复用 I/O 的经典实现,但在高并发场景下性能受限。

int select(int maxfdp, fd_set *readfds, fd_set *writefds,
           fd_set *errorfds, struct timeval *timeout);
  • 文件描述符限制:单个进程监视的 FD 数量通常上限为 1024(__FD_SETSIZE),虽然可修改但开销大。
  • 轮询效率:select 返回就绪的 FD 集合后,应用程序必须遍历整个集合才能找出哪些发生了事件。监听越多,遍历越慢。
  • 内存拷贝:每次调用都需要将用户空间的 FD 集合复制到内核空间,带来额外开销。
  • 触发方式:采用水平触发(Level Triggered)。如果未处理完就绪事件,下次调用仍会通知。
  • 优缺点:优点是跨平台性好,超时精度可达微秒;缺点是 FD 数量有限,且大量空闲连接时效率低。

fork, wait, exec 函数

这三个函数构成了 Linux 下进程管理的基石。

  • fork:复制当前进程。父进程返回子进程 PID,子进程返回 0。此时两个进程共享页表,采用写时复制(Copy-On-Write)机制,真正写入时才分配新内存。
  • exec:加载新的 ELF 文件替换当前进程映像。执行成功后无返回值,子进程开始运行新程序。
  • wait:父进程阻塞等待子进程状态改变。成功返回 0,错误返回 -1。配合 fork 使用可避免僵尸进程。

掌握这些底层机制,在处理嵌入式资源管理和进程通信时会更加得心应手。

目录

  1. 嵌入式 C/C++ 核心考点:内存管理、多态与系统调用
  2. 一、变量与内存管理
  3. 全局变量和静态变量的区别
  4. 全局变量能否定义在头文件中?
  5. 局部变量能否和全局变量重名?
  6. 二、C++ 面向对象特性
  7. 为什么析构函数必须是虚函数?
  8. 为什么 C++ 默认析构函数不是虚函数?
  9. 重载和覆盖有什么区别?
  10. 虚函数表如何实现运行时多态?
  11. 三、系统编程基础
  12. C 语言函数调用的底层原理
  13. select 函数详解
  14. fork, wait, exec 函数

更多推荐文章

查看全部
  • 基于 Vue 和 SpringBoot 的疫苗接种管理系统设计与实现
  • C++ 虚函数表实现机制详解
  • Conda 虚拟环境创建、多 Python 版本管理与环境切换指南
  • 鸿蒙 Web 生态下 angular_bloc 状态管理适配实战
  • C++ 类型转换机制详解:四种操作符与重载实践
  • 高精度混凝土缺陷与桥梁病害巡检数据集(YOLO 格式)
  • 新手必看!ClaudeCode+Figma-MCP 前端代码 1:1 还原 UI 的入门指南
  • Qwen2.5-7B-Instruct 与 vLLM 离线推理性能分析
  • Ollama 本地部署与运行开源大语言模型指南
  • GitHub Copilot 接入第三方 OpenAI 兼容模型及移除安全限制方法
  • CSP-S 提高组专题:倍增算法思想与应用(四)
  • 数据结构:快慢指针原理及链表环检测
  • Prompt 提示词工程核销逻辑与高效 AI 交互策略
  • C++ STL set 与 map 底层封装原理详解
  • 人工智能(AI)常见面试题及答案汇总
  • 国内主流 AI 工具对比:豆包、元宝、千问、Kimi、DeepSeek、MiniMax、GLM
  • 国产大模型全景清单与行业应用趋势分析
  • 基于 FPGA 的北斗导航自适应抗干扰算法设计与实现
  • 医疗 AI 场景下的逻辑回归算法原理与应用实战
  • RabbitMQ 后端消息队列技术详解

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online