结构体为成员分配独立内存,总大小为成员大小之和加填充;联合体所有成员共享同一内存,总大小等于最大成员大小。

C++的结构体(
struct
union
当我初次接触C++的内存布局时,
struct
union
struct
而
union
union
int
double
union
double
double
int
union
union
选择结构体而非联合体,通常是出于数据完整性、可读性和维护性的优先考虑。结构体的核心价值在于它能够将一组逻辑上相关但物理上独立的数据项聚合在一起。想象一下,你正在设计一个表示“学生”的数据类型,你肯定会需要同时存储学生的姓名(字符串)、学号(整数)、年龄(整数)和平均成绩(浮点数)。这些信息是并存的,你不会说“学生要么有姓名,要么有学号”,它们是共同构成一个学生的完整画像。在这种情况下,
struct Student { std::string name; int id; int age; double gpa; };立即学习“C++免费学习笔记(深入)”;
而联合体,它的最佳应用场景则聚焦于内存效率和类型多态性(运行时根据需要存储不同类型数据)的特定场景。一个典型的例子是,当你需要定义一个“值”类型,这个值可能是一个整数,也可能是一个浮点数,或者是一个字符串,但你明确知道在任何给定时间点,它只会是其中一种。例如,一个解析器可能在处理一个抽象语法树节点时,这个节点的值可能是数字常量,也可能是字符串常量。如果使用
struct
union
union Value { int i; double d; char* s; };union
struct TaggedValue { enum Type { INT, DOUBLE, STRING } type; union Value data; };std::variant
union
union
C++标准对结构体和联合体的内存对齐与填充有着明确但又留有一定实现自由度的规定。其核心目的是为了确保程序在不同硬件架构上能够高效运行,因为许多处理器在访问非对齐数据时会效率低下,甚至会引发硬件异常。
对于结构体而言,标准规定:
char
int
char
int
char
int
举个例子:
struct Example {
char c1; // 1 byte
int i; // 4 bytes
char c2; // 1 byte
short s; // 2 bytes
};
// 假设默认对齐是4字节
// c1 (1 byte) [c1][pad][pad][pad]
// i (4 bytes) [i ][i ][i ][i ]
// c2 (1 byte) [c2][pad][pad]
// s (2 bytes) [s ][s ]
// 总大小:1 (c1) + 3 (pad) + 4 (i) + 1 (c2) + 1 (pad) + 2 (s) + 2 (pad) = 14 bytes
// 实际上,最大对齐是int的4字节,所以总大小会是4的倍数,16字节。
// [c1][pad][pad][pad][i ][i ][i ][i ][c2][pad][s ][s ][pad][pad][pad][pad]
// sizeof(Example) 可能会是16这种填充虽然增加了内存占用,但显著提升了CPU访问效率。
对于联合体而言,规则则简化得多:
union Data {
char c; // 1 byte
short s; // 2 bytes
int i; // 4 bytes
double d; // 8 bytes
};
// 最大成员是double,占用8字节,对齐要求通常也是8字节。
// 所以 sizeof(Data) 会是8。
// 无论你存c, s, i, 还是d,都占用这8字节。这意味着联合体内部不会有成员之间的填充,因为它本质上只是一个足够大的内存块,可以容纳任何一个成员。末尾填充可能存在,以确保整个联合体实例能满足其最大成员的对齐要求。编译器通常提供
#pragma pack
__attribute__((packed))
在现代C++的面向对象设计(OOD)中,裸的(plain)联合体(
union
以上就是C++的结构体和联合体在内存分配和布局上有何关键差异的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号