为什么不是sizeof等于每个成员的sizeof之和?
为什么'sizeof'运算符返回的结构体积比结构体的总尺寸要大?
这是因为添加了填充以满足对齐约束。 数据结构调整会影响程序的性能和正确性:
SIGBUS
)。 以下是使用x86处理器的典型设置(全部使用32位和64位模式)的示例:
struct X
{
short s; /* 2 bytes */
/* 2 padding bytes */
int i; /* 4 bytes */
char c; /* 1 byte */
/* 3 padding bytes */
};
struct Y
{
int i; /* 4 bytes */
char c; /* 1 byte */
/* 1 padding byte */
short s; /* 2 bytes */
};
struct Z
{
int i; /* 4 bytes */
short s; /* 2 bytes */
char c; /* 1 byte */
/* 1 padding byte */
};
const int sizeX = sizeof(struct X); /* = 12 */
const int sizeY = sizeof(struct Y); /* = 8 */
const int sizeZ = sizeof(struct Z); /* = 8 */
可以通过对齐排序成员(按照基本类型的大小进行排序)(如上面示例中的结构Z
)来排列结构的大小,从而最小化结构的大小。
重要提示:C和C ++标准都声明结构对齐是实现定义的。 因此,每个编译器可能会选择以不同方式对齐数据,从而导致不同的和不兼容的数据布局。 因此,在处理将由不同编译器使用的库时,理解编译器如何对齐数据很重要。 某些编译器具有命令行设置和/或特殊的#pragma
语句来更改结构对齐设置。
打包和字节对齐,如C常见问题中所述:
这是为了对齐。 许多处理器无法访问2字节和4字节数量(例如,整数和长整数),如果它们在每一个方向都被塞住。
假设你有这样的结构:
struct {
char a[3];
short int b;
long int c;
char d[3];
};
现在,你可能认为应该可以将这种结构打包到内存中,如下所示:
+-------+-------+-------+-------+
| a | b |
+-------+-------+-------+-------+
| b | c |
+-------+-------+-------+-------+
| c | d |
+-------+-------+-------+-------+
但是如果编译器像这样安排它,那么在处理器上处理起来要容易得多:
+-------+-------+-------+
| a |
+-------+-------+-------+
| b |
+-------+-------+-------+-------+
| c |
+-------+-------+-------+-------+
| d |
+-------+-------+-------+
在打包版本中,请注意您和我看到b和c字段如何环绕至少有点困难? 简而言之,处理器也很难。 因此,大多数编译器会像这样填充结构(就像添加额外的不可见字段一样):
+-------+-------+-------+-------+
| a | pad1 |
+-------+-------+-------+-------+
| b | pad2 |
+-------+-------+-------+-------+
| c |
+-------+-------+-------+-------+
| d | pad3 |
+-------+-------+-------+-------+
如果你希望结构与GCC具有一定的大小,例如使用__attribute__((packed))
。
在Windows上,使用带有/ Zp选项的cl.exe编译器时,可以将对齐方式设置为一个字节。
通常,CPU可以更容易地访问4(或8)倍数的数据,这取决于平台以及编译器。
所以这基本上是一个对齐的问题。
你需要有充分的理由来改变它。
链接地址: http://www.djcxy.com/p/12511.html上一篇: Why isn't sizeof for a struct equal to the sum of sizeof of each member?