類對象大小 = 非靜態成員變量總和 + 編譯器為 CPU 訪問效率插入的填充字節 + 虛函數表指針(如有虛函數)。
本文聚焦數據對齊填充規則。
第一個成員偏移量為 0。後續成員偏移量必須是該成員大小的整數倍。32 位系統下 int 4 字節,偏移量為 4 的倍數;double 8 字節,偏移量為 8 的倍數。
結構體作為成員時,其起始偏移量必須是內部最大成員大小的整數倍。如內部含 double(8 字節),則外部結構體中該成員偏移量為 8 的倍數。
結構體總大小必須是所有成員中最大類型大小的整數倍(嵌套結構體按其內部最大成員算)。不足時尾部填充。
struct A {
char a; // 偏移 0,大小 1
// 填充 7 字節 (對齊 double)
double b; // 偏移 8,大小 8
int c; // 偏移 16,大小 4
// 填充 4 字節 (整體對齊 8)
}; // sizeof(A) = 24
struct B {
int a; // 偏移 0,大小 4
// 填充 4 字節 (對齊 A 的最大成員 double=8)
A b; // 偏移 8,大小 24
char c; // 偏移 32,大小 1
// 填充 7 字節 (整體對齊 8)
}; // sizeof(B) = 40
#pragma pack(n) 指定按 n 字節對齊。實際對齊數 = min(成員自身對齊數, n)。
n=1:取消對齊,緊湊排列n=4:double 按 4 字節對齊而非 8#pragma pack():恢復默認對齊
#pragma pack(4)
struct C {
char a; // 偏移 0
double b; // 偏移 4 (min(8,4)=4)
int c; // 偏移 12
}; // sizeof(C) = 16 (max align=4)
#pragma pack()
#include
using namespace std;
struct A { char a; double b; int c; };
struct B { int a; A b; char c; };
int main() {
cout << "sizeof(A) = " << sizeof(A) << endl; // 24
cout << "sizeof(B) = " << sizeof(B) << endl; // 40
A obj;
cout << "&obj.a = " << (void*)&obj.a << endl;
cout << "&obj.b = " << (void*)&obj.b << endl;
cout << "&obj.c = " << (void*)&obj.c << endl;
return 0;
}
double, int, char)offsetof(Struct, member) 獲取成員偏移量內存對齊是 C/C++ 為換取 CPU 訪問效率而引入的編譯器行為。理解三大規則(成員、嵌套、整體)能準確預測 sizeof 結果。#pragma pack 提供控制手段,但除非有明確跨平台二進制兼容需求,一般不建議修改默認對齊。