为何结构体B与结构体D的sizeof计算结果存在差异?
结构体大小计算差异原因解析
测试代码
#include <iostream> using namespace std; struct A{ virtual void f(){}; int a; char ch; }; struct B : public A{ char d; }; struct C{ double dd; int a; char ch; }; struct D : public C{ char d; }; int main(){ B b; D d; cout<<"b="<<sizeof(b)<<endl; cout<<"d="<<sizeof(d)<<endl; }
运行结果
b=16 d=24
差异原因分析
以下基于64位系统(指针占8字节,默认8字节对齐规则)展开:
1. 结构体A与B的内存布局
- 结构体A:包含虚函数表指针(8字节)、int类型成员
a(4字节)、char类型成员ch(1字节)。有效成员总长度为13字节,由于A的对齐边界由8字节的虚指针决定,需要填充3字节到16字节,因此sizeof(A)=16。 - 结构体B:继承A并新增char成员
d。由于A包含虚函数,不属于C++的标准布局类型,编译器会做优化:将d直接放在A末尾的填充字节中(偏移13的位置)。此时B的有效成员总长度为14字节,对齐到8字节的倍数后仍为16字节,所以sizeof(B)=16。
2. 结构体C与D的内存布局
- 结构体C:包含double类型成员
dd(8字节)、int类型成员a(4字节)、char类型成员ch(1字节)。有效成员总长度为13字节,对齐边界由8字节的double决定,填充3字节后sizeof(C)=16。 - 结构体D:继承C并新增char成员
d。C是标准布局类型(无虚函数、无虚基类,成员访问权限一致),根据C++规则,派生类成员不能占用基类的填充字节,必须放在基类完整大小之后(偏移16的位置)。此时D的有效成员总长度为17字节,对齐到8字节的倍数后为24字节,因此sizeof(D)=24。
简单来说,两者的核心差异在于基类是否为标准布局类型:非标准布局基类允许派生类成员填充其末尾的预留空间,而标准布局基类则不允许,最终导致了结构体大小的不同。
内容的提问来源于stack exchange,提问作者haojie zhou
相关产品推荐
相关产品推荐

