Reputation: 1843
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
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