user968000
user968000

Reputation: 1843

Understanding padding in structure

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);
}

Output is:

./a.out
size of address 12 
zip 0x11 
state0 0x1413 state1 0x1615 

Upvotes: 3

Views: 689

Answers (1)

dbush
dbush

Reputation: 223689

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.

After that the next available offset is 6 so two more padding bytes are needed for country to be aligned on a 4 byte boundary. So then the offset of country is 8.

So now the structure looks like this:

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;

For more details on how padding is usually implemented, see this guide.

Upvotes: 6

Related Questions