Confusion in Structure Member Alignment

2019-07-16 11:38发布

问题:

typedef struct structc_tag
{
   char        c;
   double      d;
   int         s;
} structc_t;

I read in a blog that this will take 24 bytes of data:

sizeof(char) + 7 byte padding + sizeof(double) + sizeof(int) + 4 byte padding = 1 + 7 + 8 + 4 + 4 = 24 bytes.

My question is why the 7 byte padding, why can't we use 3bytes of padding there and utilise next 8 bytes for double? And what is the need for last 4 bytes?

回答1:

You need to consider what the happens if you allocate an array of these structures with malloc():

structc_t *p = malloc(2 * sizeof *p);

Consider a platform where sizeof(double) == 8, sizeof(int) == 4 and the required alignment of double is 8. malloc() always returns an address correctly aligned for storing any C type - so in this case a will be 8 byte aligned. The padding requirements then naturally fall out:

  • In order for a[0].d to be 8-byte aligned, there must therefore be 7 bytes of padding after a[0].c;

  • In order for a[1].d to be 8-byte aligned, the overall struct size must be a multiple of 8, so there must therefore be 4 bytes of padding after a[0].s.

If you re-order the struct from largest to smallest:

typedef struct structc_tag
{
   double      d;
   int         s;
   char        c;
} structc_t;

...then the only padding required is 3 bytes after .c, to make the structure size a multiple of 8. This results in the total size of the struct being 16, rather than 24.



回答2:

It's platform dependent, but it depends on what double is aligned to. If it's aligned to 8 bytes, which appears to be this case, 3 bytes of padding won't cut it.

If double was aligned to 4 bytes, you'd be right and 3 bytes of padding would be used.