理解 C 中的结构填充

问题描述 投票:0回答:2

我通过数据对齐概念理解,int和floats应该存储在可以被4整除的地址(起始字节地址)。根据它,下面结构的大小是12

 typedef struct{
    char A;
    int B;
    float C;
}y;

我对以上结构的尺寸毫无疑问的了解 现在我的疑问是下面结构的大小

typedef struct {
    double A;
    char B;
    char C;
}x;

x的大小是16。我的疑问是所使用的两个字符可以分配在2个字节中,这样整个结构使用10个字节的数据 剩下的 2 个字节可以在声明时用于分配给另一个短整型,对吗?

但是编译器使用 16 字节数据并填充其他 6 个单元。我不明白为什么它会浪费另外 6 个单元格,如果它可以在声明它们时将它们用于另一个变量?谁能帮助我理解上述概念?(我假设 int 、 float 和 double 的大小分别为 4,4,8 字节。)

c structure padding
2个回答
3
投票

x
的情况下,它包含一个
double
(在您的情况下)大小为 8。这意味着整个结构需要是该大小的倍数才能形成
x
数组正确对齐。

由于数组是连续分配的,因此数组的每个成员都紧跟在内存中的前一个成员之后。如果

x
的大小为 10,则对于数组,第二个元素的
A
成员的偏移量为 10。为了正确对齐,每个数组成员需要以最大元素大小的倍数开始。因此该结构在末尾包含填充来实现此目的。


0
投票
/*

If the alignment requirement (_Alignof) of a data type is x bytes, then every
variable of that data type will be (on almost all implementations) allocated
starting at an address which is divisible by x.

The alignment requirement of every data type is always a non-negative integral
power of 2 (i.e. 1, 2, 4, 8, 16, etc.).

////////////////////////////////////////////////////////////////////////////////

For fundamental data types (int, double, etc.), _Alignof (T) is (on almost all
implementations) equal to sizeof (T).

So, if _Alignof (int) == sizeof (int) == 4, then every variable of data type int
will be allocated starting at an address which is divisible by 4.

And, if _Alignof (double) == sizeof (double) == 8, then every variable of data
type double will be allocated starting at an address which is divisible by 8.

////////////////////////////////////////////////////////////////////////////////

For structures, _Alignof (T) is equal to the maximum alignment requirement of
its members.

So, for structures, _Alignof (T) is generally not equal to sizeof (T).

However, sizeof (T) must always be divisible by _Alignof (T).
This ensures that in an array of structures, every element will be allocated
starting at an address which is divisible by _Alignof (T).

////////////////////////////////////////////////////////////////////////////////

struct s
{
    int x;
    double y;
    int z;
};

_Alignof x == 4, _Alignof y == 8 and _Alignof z == 4.

So, _Alignof (struct s) == 8, since the maximum alignment requirement of its
members is 8.

This means that every variable of data type struct s will be allocated starting
at an address which is divisible by 8.

Let the starting address of a variable of data type struct s be 200.

Since _Alignof x == 4, and 200 is divisible by 4, therefore x will be allocated
at the addresses 200 to 203.

Since _Alignof y == 8, and 204 is not divisible by 8, therefore the addresses
204 to 207 will be wasted, and y will be allocated at the addresses 208 to 215.

Since _Alignof z == 4, and 216 is divisible by 4, therefore z will be allocated
at the addresses 216 to 219.

Now, since sizeof (T) must always be divisible by _Alignof (T), which is 8,
therefore the addresses 220 to 223 will be wasted.

Finally, sizeof (struct s) will be 24.

////////////////////////////////////////////////////////////////////////////////

Sometimes, rearranging the members of a structure may reduce its size.

For eg., let struct s be written in the following manner -

struct s
{
    int x;
    int z;
    double y;
};

_Alignof x == 4, _Alignof z == 4 and _Alignof y == 8.

So, _Alignof (struct s) == 8, since the maximum alignment requirement of its
members is 8.

Let the starting address of a variable of data type struct s be 200.

Since _Alignof x == 4, and 200 is divisible by 4, therefore x will be allocated
at the addresses 200 to 203.

Since _Alignof z == 4, and 204 is divisible by 4, therefore z will be allocated
at the addresses 204 to 207.

Since _Alignof y == 8, and 208 is divisible by 8, therefore y will be allocated
at the addresses 208 to 215.

Finally, sizeof (struct s) will be 16.

*/
© www.soinside.com 2019 - 2024. All rights reserved.