字节对齐原则
这个问题也是困扰了我很久的一个问题:
为了加快数据存取的速度,编译器默认情况下会对结构体成员和结构体本身存储位置进行处理,使其存放的起始地址是一定字节数的倍数,而不是顺序存放,称为字节对齐.
设对齐字节数为n(n = 1,2,4,8,16),每个成员内存长度为Li,Max(Li)为最大的成员内存长度,字节对齐规则是:
1. 结构体对象的起始地址能够被Max(Li)所整除;
2. 结构体中每个成员相对于起始地址的偏移量,即对齐值应是min(n,Li)的倍数.若不满足对齐值的要求,编译器会在成员之间填充若干个字节;
3. 结构体的总长度值应是min(n,Max)(Li)的倍数,若不满足总长度值的要求,编译器在为最后一个成员分配空间后,会在其后填充若干个字节.
(VC默认的对齐字节数n=8)
开不懂,请看下面例子:
#include <iostream> using namespace std; // 1加1+编译器补充的2个再加上int 的4个(编译器自动加的) typedef struct node1 // 1+1+(2)+4 = 8 { char c1; char c2; int a; }str1 ; typedef struct str2 // 1+(3)+4+1+(3) = 12 { char c1; int a; char c2; }str2 ; typedef struct str3 // 5+(3)+4+2+(2) = 16 { char c1[5]; int b; short c; }str3 ; typedef struct str4 // 5+(1)+(2)+4 = 12 { char c1[5]; short c; int b; }str4 ; typedef struct str5 // 1+1+(6)+8 = 16 { char c1; char c2; double a; }str5 ; typedef struct str6 // 1+(7)+8+1+(7) = 24 { char c1; double a; char c2; }str6 ; typedef struct str7 { char c1; str1 s; // 相当于吧str1的结构放在这 char,char,int double b; }str7 ; // 1+1+1+(1)+4+4 = 12 int main() { str1 s1; str2 s2; str3 s3; str4 s4; str5 s5; str5 s6; str7 s7; str8 s8; cout << "s1 = " << sizeof(s1)<<endl; cout << "s2 = " << sizeof(s2)<<endl; cout << "s3 = " << sizeof(s3)<<endl; cout << "s4 = " << sizeof(s4)<<endl; cout << "s5 = " << sizeof(s5)<<endl; cout << "s6 = " << sizeof(s6)<<endl; cout << "s7 = " << sizeof(s7)<<endl; cout << "s8 = " << sizeof(s8)<<endl; return 0; }
图解:
str1
str2:
str3:
str4:
str5:
str6: