sizeof 返回编译期确定的完整对象对齐后字节总数,不含虚基类偏移、运行时开销、动态分配内存及静态成员,受对齐填充、vptr、字段顺序和继承方式影响。

用 sizeof 就能拿到编译期精确大小,但必须理解它测的是什么
sizeof 是唯一在编译期求值、返回 size_t 的运算符,它给出的是该类型**完整对象**(不含虚基类偏移调整、不含运行时多态开销)在内存中所占的**对齐后字节总数**。注意:它不关心对象是否被构造,也不依赖任何实例——sizeof(MyClass) 和 sizeof(obj) 效果完全一样。
常见误解是以为它会包含动态分配内存(比如 std::vector 内部的堆内存),其实不会:sizeof(std::vector<int>)</int> 通常只有 24 或 32 字节(取决于平台和 STL 实现),仅含三个指针(start/finish/end_of_storage)及其对齐填充,不计入元素实际占用的堆空间。
实操建议:
- 直接写
static_assert(sizeof(MyClass) == 16, "unexpected size");做编译期校验 - 对模板类型,用
sizeof(T)是合法且常用的元编程手段 - 若类含静态成员,
sizeof不计入它们——静态成员不属对象实例布局
为什么 sizeof 结果常比字段总和大?对齐和填充是关键
编译器会在字段之间或末尾插入填充字节(padding),确保每个成员按其自然对齐要求(如 int 通常需 4 字节对齐,double 需 8 字节)存放,并让整个结构体满足其最严格成员的对齐约束(即 alignof(MyClass))。
立即学习“C++免费学习笔记(深入)”;
例如:
struct A {
char a; // offset 0
int b; // offset 4(跳过 3 字节 padding)
char c; // offset 8
}; // sizeof(A) == 12,不是 1+4+1=6实操建议:
- 用
#pragma pack(1)可禁用填充,但会降低访问性能,且可能触发硬件异常(如 ARM 对非对齐访问报错) - 用
alignas显式提升对齐要求(如alignas(16) struct X { ... };),这会让sizeof向上取整到 16 的倍数 - 字段声明顺序影响填充量:把大类型放前面、小类型放后面,通常能减少总大小
虚函数、虚继承会让 sizeof 突然变大,别只看字段
只要类有虚函数(哪怕一个),编译器就会为每个实例隐式添加一个虚表指针(vptr),通常是 8 字节(64 位系统)。这个指针放在对象开头(多数 ABI),直接计入 sizeof 结果。
虚继承更复杂:它引入虚基类表指针(vbptr),还可能导致额外的偏移字段。例如:
struct Base { virtual void f() {} }; // sizeof == 8(仅 vptr)
struct Derived : Base { int x; }; // sizeof == 16(vptr + x + padding)实操建议:
- 检查
sizeof前先确认类是否有virtual函数或virtual继承路径 - 用
offsetof配合static_assert校验关键字段偏移,比只看sizeof更可靠 - 调试时可用
gdb的p/x &obj和p/x &obj.field手动验证布局
标准库容器和智能指针的 sizeof 很小,别误判内存开销
std::string、std::shared_ptr、std::unique_ptr 这些类型自身尺寸固定且很小(通常 8–32 字节),但它们管理的资源(堆内存、引用计数块)完全不反映在 sizeof 里。这是初学者最容易踩的坑。
例如:
std::string s(1000, 'x'); static_assert(sizeof(s) == 24, "likely true on libstdc++"); // ✅ 编译通过 // 但 s 占用的 1000 字节堆内存,sizeof 完全不体现
实操建议:
- 若需估算总内存占用,必须区分“对象本身”和“其所拥有的资源”,后者需额外分析(如
s.capacity()、ptr.use_count()) - 序列化或跨进程传递前,绝不能只靠
sizeof判断能否memcpy—— 指针成员、虚函数、非 POD 类型都会导致未定义行为 - 对
std::array<t n></t>这种纯聚合类型,sizeof才真正等于N * sizeof(T),可安全 memcpy
真正难的不是获取数字,而是理解这个数字背后代表的内存布局契约:对齐规则、ABI 约定、编译器优化策略,以及你是否在跟裸内存打交道。一旦涉及指针、虚函数、动态分配,sizeof 就只是冰山一角。


















