结构体内可以有多种类型数据, 默认按照成员声明顺序, 在内存中按照默认对齐方式存储; 也可以使用 "#pragma pack(N)" 指定对齐字节数
默认对齐方式
- 结构体第一个成员的地址和结构体地址相同
- 对齐时, 成员会相对结构体地址偏移, 产生偏移量, 这个偏移量要是成员大小的整数倍
- 结构体的总大小, 需要是长度最大的成员的整数倍;
- 对齐会产生填充字节
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
struct PackS{ char c; double d; int i; }; PackS packS = {'A', 3, 3}; cout << "char 大小 = " << sizeof(char) << endl; cout << "double 大小 = " << sizeof(double) << endl; cout << "int 大小 = " << sizeof(int) << endl; cout << "char 偏移 = " << offsetof(PackS, c) << endl; cout << "double 偏移 = " << offsetof(PackS, d) << endl; cout << "int 偏移 = " << offsetof(PackS, i) << endl; cout << "结构体大小 = " << sizeof(packS) << endl; // 输出 char 大小 = 1 double 大小 = 8 int 大小 = 4 char 偏移 = 0 double 偏移 = 8 int 偏移 = 16 结构体大小 = 24 |
这个结构体大小为 24 个字节;
char 占用1个字节;
double大小为8, 偏移量为8的整数倍, 所以前面补充7个字节;
int大小为4, 现在是1+7+8+4=20, 需要是最大长度8的整数倍, 所以加上4, 最后长度是 20+4=24;
指定对齐方式
- 结构体第一个成员的地址和结构体地址相同
- 如果 N 大于成员大小, 该成员按照默认对齐方式; N 小于成员大小, 偏移量为 N 的整数倍
- 结构体大小是 N 的整数倍
- 如果 N 大于结构体内最大成员的大小, 则 N 不起作用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
#pragma pack(2) struct PackS{ char c; double d; int i; }; #pragma apop() PackS packS = {'A', 3, 3}; cout << "char 大小 = " << sizeof(char) << endl; cout << "double 大小 = " << sizeof(double) << endl; cout << "int 大小 = " << sizeof(int) << endl; cout << "char 偏移 = " << offsetof(PackS, c) << endl; cout << "double 偏移 = " << offsetof(PackS, d) << endl; cout << "int 偏移 = " << offsetof(PackS, i) << endl; cout << "结构体大小 = " << sizeof(packS) << endl; // 输出 char 大小 = 1 double 大小 = 8 int 大小 = 4 char 偏移 = 0 double 偏移 = 2 int 偏移 = 10 结构体大小 = 14 |
char 占用一个字节; 1
double 偏移量是2的倍数,所以前面补1个字节, 自身占用8个字节; 1+8
int 偏移量是10,不用补充字节; 4
总大小为: 1+1+8+4=14; 因为14是2的整数倍,所以 int 之后不用补充字节
如果 N 为1的话, 则没有补充字节, 大小为成员的实际大小之和;
0 Comments