Understanding padding in structure

use*_*000 2 c

To understand more about padding I created this structure. Why is the output of state 0x1413 and not 0x1615. I am expecting compiler will pad 3 bytes after zip and should give output as 0x1615.

typedef struct
{
    uint8_t zip; // I am assuming 3 bytes will be padded after this.
    uint16_t state[2]; // 4 bytes
    uint32_t country; //4 bytes
} address;

int main()
{
    uint8_t buf[] = {0x11, 0x12, 0x13, 0X14, 0x15, 0x16,0x17, 0x18, 0x09, 0x0A, 0x0B, 0x0C, 0X0D, 0x0E, 0x0F};
    address *val;
    val = (address*)buf;
    printf("size of address %lu \n",sizeof(address));
    printf("zip 0x%0x \n",val->zip);
    printf("state0 0x%0x state1 0x%0x \n",val->state[0],val->state[1]);
    printf("country 0x%0x \n",val->country);
}
Run Code Online (Sandbox Code Playgroud)

Output is:

./a.out
size of address 12 
zip 0x11 
state0 0x1413 state1 0x1615 
Run Code Online (Sandbox Code Playgroud)

dbu*_*ush 5

Padding is typically based on the base type of each of its members.

The member state is an array of uint16_t, so this field is aligned on a 2 byte boundary even though the entire array is 4 bytes. What's important is that each member of the array is correctly aligned. So there is 1 byte of padding after zip to align state and state starts at offset 2.

之后,下一个可用偏移量为6,因此需要在两个country4个字节的边界上对齐另外两个填充字节。因此,偏移量country为8。

因此,现在的结构如下所示:

typedef struct
{
    uint8_t zip;         // offset 0
    // 1 byte padding
    uint16_t state[2];   // offset 2
    // 2 bytes padding
    uint32_t country;    // offset 8
} address;
Run Code Online (Sandbox Code Playgroud)

有关通常如何实现填充的更多详细信息,请参阅本指南