1

A tutorial on data padding says that the char c following int i in the C struct below needs 1 padding byte.

struct test2
{
    int i;
    // 4 bytes
    char c;
    // 1 byte
    // 1 padding byte. <-- question here
    short s;
    // 2 bytes
};

I would like to understand why it is not 3 bytes padding instead, given that the memory access is on 32 bits in this case?

zell
  • 9,830
  • 10
  • 62
  • 115
  • 1
    I think its because you have `short` after `char`, try removing `short`, you should see `sizeof(test2)` as 8 – IrAM Dec 23 '20 at 05:47

2 Answers2

4

The alignment of each individual member is what matters. Consider the alignment requirements of each type. For an int, in your case, it is 4 bytes. For a char, it is naturally 1. How about a short? Well on your architecture it seems to be 2 bytes. We want to have each member aligned based on its own alignment requirements.

Since int is the first member, we don't need any padding (but this does affect the size of the struct as a whole). Then, we have a char, which has the loosest requirement, so we don't need to pad for it. Then comes a short. It needs to be aligned to 2 bytes. We are currently at an offset of 5 bytes, so we need a single padding byte to get the short aligned properly. All in all that gives us 8 bytes, and that also fits the alignment of the whole structure, so no additional padding is needed at the end.

In general, the smallest size of a structure will be achieved by ordering members from strongest alignment requirements to weakest. This isn't necessarily the only order to get the smallest size, but it is guaranteed that no other ordering will be smaller.

user975989
  • 2,578
  • 1
  • 20
  • 38
2

From Unaligned Memory Accesses

Unaligned memory accesses occur when you try to read N bytes of data starting from an address that is not evenly divisible by N (i.e. addr % N != 0). For example, reading 4 bytes of data from address 0x10004 is fine, but reading 4 bytes of data from address 0x10005 would be an unaligned memory access.

The size of int is 4 bytes, size of short is 2 bytes, size of char is 1 byte (64 bit system).

Let's assume the starting address as 0x0000.
So, int i occupies from 0x0000 to 0x0003.
char c is stored at 0x0004 (since, address is divisible by 1).

Assume there is no 1 byte padding after char c, Then, short s will be stored at 0x0005, which is not divisble by 2. This causes unaligned memory accesses.

To prevent this, we add 1 byte padding after char c. After padding 1 byte, short s will be stored ar 0x0006, which is divisble by 2.

Krishna Kanth Yenumula
  • 2,533
  • 2
  • 14
  • 26