To understand why the struct must be padded to 16 bytes when rearranging the members in the order i1, i2, i3, c1, c2, c3, let’s break down the concept of padding and alignment in C structs.

Struct Definition and Alignment

Consider the struct ints_and_chars defined as:

struct ints_and_chars {
    int i1;
    int i2;
    int i3;
    char c1;
    char c2;
    char c3;
};

In this struct:

  • int typically requires 4-byte alignment.
  • char typically requires 1-byte alignment.

Memory Layout Without Padding

If we place the members in memory without considering alignment, the layout would be:

| i1 | i2 | i3 | c1 | c2 | c3 |

Since each int takes 4 bytes and each char takes 1 byte, the total size would be:

  • 3 int variables: (3 \times 4 = 12) bytes
  • 3 char variables: (3 \times 1 = 3) bytes
  • Total: (12 + 3 = 15) bytes

Alignment and Padding

However, memory alignment rules require that each int starts at an address that is a multiple of 4. Let’s see how alignment would impact the layout:

Offset:  0    4    8    12   13   14   15
        | i1 | i2 | i3 | c1 | c2 | c3 | P |
  • i1 is aligned at 0 (0 % 4 == 0)
  • i2 is aligned at 4 (4 % 4 == 0)
  • i3 is aligned at 8 (8 % 4 == 0)
  • c1 can be placed at 12 (12 % 1 == 0)
  • c2 can be placed at 13 (13 % 1 == 0)
  • c3 can be placed at 14 (14 % 1 == 0)

Now, if you want to align the next struct element in an array properly, it must start at a multiple of 4 due to the int alignment requirements.

If we have the struct exactly as described without padding, the next struct in an array would start at 15, which is not a multiple of 4. Therefore, a padding byte P is added after c3 to ensure the next struct starts at a 4-byte aligned address:

Offset:  0    4    8    12   13   14   15  | 16
        | i1 | i2 | i3 | c1 | c2 | c3 | P  | i1 ...

The padding byte P is placed at offset 15, making the total size of the struct 16 bytes. This ensures that if we have an array of such structs, each struct will start on a 4-byte aligned address, maintaining alignment requirements for int.

Conclusion

The padding to 16 bytes ensures that any subsequent ints_and_chars struct in an array will start at an address that is a multiple of 4. This is crucial for maintaining alignment requirements for int members within the struct.