|
编译器尝试以防止数据未对齐的方式分配数据。
对于简单的数据类型,编译器将分配是数据类型的大小(以字节为单位)的倍数的地址。 例如,编译器将地址分配给类型为 long 且是 4 的倍数的变量,并将地址的最底部 2 位设置为零。
编译器还以自然对齐结构的每一个元素的方式填充结构。 来看看下面代码示例中的结构 struct x_:
C++
struct x_
{
char a; // 1 byte
int b; // 4 bytes
short c; // 2 bytes
char d; // 1 byte
} bar[3];
编译器填充此结构以自然强制实施对齐方式。
下面的代码示例展示了编译器如何将填充的结构置于内存中:
C++
// Shows the actual memory layout
struct x_
{
char a; // 1 byte
char _pad0[3]; // padding to put 'b' on 4-byte boundary
int b; // 4 bytes
short c; // 2 bytes
char d; // 1 byte
char _pad1[1]; // padding to make sizeof(x_) multiple of 4
} bar[3];
两个声明都将 sizeof(struct x_) 作为 12 个字节返回。
第二个声明包括两个填充元素:
char _pad0[3],对齐 4 字节边界上的 int b 成员。
char _pad1[1] 用于在 4 字节边界上对齐结构 struct _x bar[3]; 的数组元素。
填充以允许自然访问的方式对齐 bar[3] 的元素。
下面的代码示例展示了 bar[3] 的数组布局:
Output
adr offset element
------ -------
0x0000 char a; // bar[0]
0x0001 char pad0[3];
0x0004 int b;
0x0008 short c;
0x000a char d;
0x000b char _pad1[1];
0x000c char a; // bar[1]
0x000d char _pad0[3];
0x0010 int b;
0x0014 short c;
0x0016 char d;
0x0017 char _pad1[1];
0x0018 char a; // bar[2]
0x0019 char _pad0[3];
0x001c int b;
0x0020 short c;
0x0022 char d;
0x0023 char _pad1[1];
|
|