sizeof仅得总大小,offsetof才能获成员偏移;offsetof是编译期常量,定义于<cstddef>,返回成员相对于结构体起始的字节偏移。

用 sizeof 和 offsetof 查看结构体实际布局
直接看 sizeof 只能知道总大小,但无法得知成员偏移和填充位置。真正做布局分析,必须配合 offsetof(定义在 <cstddef> 中)。
它返回某个成员相对于结构体起始地址的字节偏移,是编译期常量,安全可靠:
#include <cstddef>
#include <iostream>
struct S {
char a;
int b;
short c;
};
int main() {
std::cout << "sizeof(S): " << sizeof(S) << "\n"; // 通常为12
std::cout << "offsetof(S, a): " << offsetof(S, a) << "\n"; // 0
std::cout << "offsetof(S, b): " << offsetof(S, b) << "\n"; // 4(不是1!)
std::cout << "offsetof(S, c): " << offsetof(S, c) << "\n"; // 8
}
输出能清晰暴露填充:成员 b 没有紧挨着 a,中间被补了 3 字节;c 前面又空出 2 字节——这是为了满足 int(4字节对齐)和 short(2字节对齐)各自的起始地址约束。
为什么改变成员声明顺序会影响 sizeof 结果
结构体成员按声明顺序依次排布,但编译器只在必要时插入填充,不重排顺序。所以把大类型往前放,能显著减少总填充量。
立即学习“C++免费学习笔记(深入)”;
-
struct Bad { char a; int b; char c; };→sizeof通常是 12(a+3pad+b+c+3pad) -
struct Good { int b; char a; char c; };→sizeof通常是 8(b+a+c+2pad,末尾补齐到 4 的倍数)
两者逻辑等价,但后者节省 4 字节。这对高频分配的小结构(如网络包头、粒子系统数据)影响真实内存带宽和缓存命中率。
注意:Good 中 a 和 c 虽然都是 char,但不会自动“打包”成一个字节字段——C++ 不做隐式位域合并,除非你显式写 struct { char a:4, c:4; };。
判断是否为标准布局以确保内存可预测
如果你打算用 memcpy 序列化、或把结构体传给 C 函数、或 reinterpret_cast 成字节数组,必须确认它是标准布局(standard layout)。否则填充位置、甚至成员顺序都可能因编译器/优化级别而异。
验证方式很简单:
#include <type_traits> static_assert(std::is_standard_layout_v<S>, "S must be standard layout");
关键约束包括:
- 不能有虚函数、虚基类
- 所有非静态成员访问控制一致(全
public或全private) - 不能有引用成员
- 若继承,只能有一个基类且它本身也得是标准布局
哪怕只加一个 private: 或一个 virtual void f() = 0;,std::is_standard_layout_v 就会变成 false,此时 offsetof 仍可用,但跨平台二进制兼容性已不可靠。
用 #pragma pack 强制紧凑布局的风险
某些场景(如硬件寄存器映射、网络协议固定格式)要求结构体完全无填充。这时可用 #pragma pack(1):
#pragma pack(push, 1)
struct Packed {
char a;
int b;
short c;
};
#pragma pack(pop)
// sizeof(Packed) == 7
但它带来两个硬伤:
- 性能损失:
int b现在可能落在非 4 字节对齐地址,x86 通常容忍但慢,ARMv7+ 可能直接触发unaligned access异常 - ABI 破坏:该结构体不能再作为函数参数值传入,也不能与标准布局类型混用——
std::is_standard_layout_v<Packed>仍为true,但对齐保证失效,memcpy安全性需额外校验
更稳妥的做法是用 alignas 显式控制单个成员对齐,或改用 std::array<std::byte, N> + 手动序列化,避免让编译器替你冒险对齐。
真正容易被忽略的是:即使你没写 #pragma pack,某些嵌入式工具链或交叉编译环境默认启用 tight packing,导致桌面端测试通过、目标板上崩溃——务必在目标平台上实测 offsetof 和 sizeof。


















