GCC struct 記憶體對齊規則 結構體起始地址需要被其中成員類型最大的大小所整除; 每個成員起始地址需要被其類型大小所整除,如int32_t類型成員記憶體對齊到4B; 如果成員有子結構體,則該子結構體成員起始地址要被其內部成員類型最大的所整除。如struct a里存有struct b,b 里有 c ...
GCC struct 記憶體對齊規則
- 結構體起始地址需要被其中成員類型最大的大小所整除;
- 每個成員起始地址需要被其類型大小所整除,如int32_t類型成員記憶體對齊到4B;
- 如果成員有子結構體,則該子結構體成員起始地址要被其內部成員類型最大的所整除。如struct a里存有struct b,b 里有 char,int,double 等元素,那 b 應該從8的整數倍開始存儲;
- 如果成員有數組,則該數組成員對齊依舊按POD類型,如uint8_t arr[4],其對齊依舊按1B;
- 如果成員有union,則按可以被union中子成員類型最大所整除處理;
- 整個結構體大小,必須要能被成員中類型最大所整除,不滿足則GCC自動填充。
結構體大小計算攻略
- 前一個成員占用大小必須被後一個成員所占空間的整數倍,不滿足則GCC自動填充,即後一個成員地址偏移到滿足可以被其整除的位置;
- 結構體大小必須被成員類型最大的所整除。
測試例子 x86-64 編譯器
/*
sizeof(typeA) = 8
addr of a: 0x7fff829ca240
addr of a.a8: 0x7fff829ca240
addr of a.b8: 0x7fff829ca241
addr of a.c32:0x7fff829ca244
*/
struct typeA {
uint8_t a8;
uint8_t b8;
uint32_t c32;
};
/*
sizeof(typeB) = 12
addr of a: 0x7ffd5c3add9c
addr of a.b8: 0x7ffd5c3add9c
addr of a.c32:0x7ffd5c3adda0
addr of a.a8: 0x7ffd5c3adda4
*/
struct typeB {
uint8_t b8;
uint32_t c32;
uint8_t a8;
};
使用記憶體對齊
使用記憶體對齊會影響到結構體起始地址偏移及結構體占用記憶體。如上面定義的typeB做修改:
struct typeA {
uint8_t b8;
uint32_t c32;
uint8_t a8;
} __attribute__ ((aligned (8)));
輸出為:
sizeof(typeA) : 16
address:
0x7ffcb3afc610
0x7ffcb3afc610
0x7ffcb3afc614
0x7ffcb3afc618
attribute align部分語法:
struct S { short f[3]; } __attribute__ ((aligned (8)));
typedef int more_aligned_int __attribute__ ((aligned (8)));