C/C++ union(共用体)用法与内存原理解析

晚来风
晚来风
发布时间:2026-10-14 | 2人浏览过
原创

在C和C++编程中,union(共用体/联合体)是一种特殊的用户定义类型,允许在同一个内存位置存储不同的数据类型。与结构体不同,共用体的所有成员共享同一块内存,这使其成为节省内存空间或在底层操作数据时非常有用的工具。然而,由于其共享机制,使用不当极易引发逻辑错误或内存泄漏。

结果或目标

理解 union 的结构体布局、大小计算方式及其与普通 struct 的本质区别,掌握在实际开发中安全使用共用体的方法。

准备条件

  • 基础 C 或 C++ 编程语言环境。
  • 对基本数据类型(如 char, int, float)的大小有所了解。
  • 理解指针与内存地址的概念。

真实操作顺序

第1步:理解 struct 与 union 的内存差异

目的:直观感受共用体如何通过覆盖技术实现内存复用。

动作:定义包含相同成员的 struct 和 union 并观察其大小。

首先看一个标准的结构体定义:

struct student {
    char mark;     // 占 1 字节
    long num;      // 通常占 4 字节
    float score;   // 占 4 字节
};

在 x86 架构下,sizeof(struct student) 的值通常为 12 bytes(考虑内存对齐)。其内存布局如下所示,各成员依次排列:

接下来,将关键字从 struct 改为 union:

union test {
    char mark;
    long num;
    float score;
};

此时,sizeof(union test) 的值为 4 bytes(即最大成员 long 或 float 的大小,受内存对齐影响)。这是因为共用体的所有成员从相同的内存地址开始存储,后赋值的成员会覆盖之前的内容。其内部重叠结构示意如下:

第2步:遵循共用体的使用规范

目的:规避因错误引用导致的未定义行为或编译错误。

在 C/C++ 中使用 union 时,必须严格遵守以下规则:

  1. 单一有效成员原则:在同一时刻,只有最后一个存入的成员是有效的,其他成员处于未知状态。
    #include <iostream>
    using namespace std;
    union test { char mark; long num; } a;
    a.mark = 'b'; cout << a.num << endl; // 输出 'b' 的 ASCII 值 98
    a.num = 10; // 此时 a.mark 已失效
  2. 禁止直接输出变量名:不能直接打印共用体变量本身,必须指定具体的成员。
    printf("%d", a); // 错误:编译器无法确定输出哪个成员
    printf("%d", a.mark); // 正确
  3. 地址一致性:所有成员的起始地址相同,因此它们的取址符值相等。
    &a.mark == &a.num == &a.score
  4. 函数参数传递:union 变量可以直接作为函数参数传入,也可以作为返回值返回(注意:早期的某些观点认为不可以,但标准 C/C++ 支持拷贝传递,只是效率问题;现代观点更倾向于使用指针以避免拷贝开销)。
    注:原文曾提及不能带回,后经验证纠正,实际上可以传递和返回,但推荐传递指针以提高性能并减少拷贝。
  5. 嵌套使用:共用体可以作为结构体的成员,结构体也可以作为共用体的成员,还可以定义共用体数组。

第3步:C++ 中的特殊限制

目的:在面向对象环境中避免构造函数/析构函数调用缺失导致的内存泄漏。

当 union 遇到 C++ 类时,情况变得复杂。如果共用体中包含带有非平凡构造函数、析构函数或复制赋值运算符的类对象,程序将无法正确编译或运行,因为编译器无法保证在这些对象被“覆盖”或销毁时调用相应的函数,从而可能导致资源泄漏。

例如,以下代码会导致编译错误:

class CA {
public:
    CA() { } // 构造函数
};
union Test { CA a; // 错误!CA 有构造函数
double d; };

解决方案:

  • 在共用体中仅包含纯数据类型的 POD (Plain Old Data) 成员。
  • 如果必须包含复杂对象,请使用该类对象的指针代替对象实例。指针本身是 POD 类型,且生命周期由程序员手动管理。

完成判断

当你能够准确写出共用体的定义,解释其内存占用为什么取最大成员大小,并能指出在 C++ 中为何要避免在共用体内放置含构造函数的类时,即标志着已掌握共用体的核心要点。

简要总结

共用体 (union) 是 C/C++ 中用于优化内存的高效工具,它允许多个不同类型的变量共享同一内存区域。使用时需牢记“互斥”特性,即同一时间仅一个成员活跃。在 C++ 开发中,务必避免在共用体内使用具有非平凡生命周期的类对象,转而使用指针或保持 C 语言的简单数据风格,以确保内存安全。

以上就是C/C++ union共用体用法与内存原理解析的详细内容,更多关于C++基础知识点、union结构设计的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表