Memory alignment in C-structs

Ivan picture Ivan · Mar 25, 2011 · Viewed 40.8k times · Source

I'm working on a 32-bit machine, so I suppose that the memory alignment should be 4 bytes. Say I have this struct:

typedef struct {
    unsigned short v1;
    unsigned short v2;
    unsigned short v3;
} myStruct;

The plain added size is 6 bytes, and I suppose that the aligned size should be 8, but sizeof(myStruct) returns me 6.

However if I write:

typedef struct {
    unsigned short v1;
    unsigned short v2;
    unsigned short v3;
    int i;
} myStruct;

the plain added size is 10 bytes, aligned size shall be 12, and this time sizeof(myStruct) == 12.

Can somebody explain what is the difference?

Answer

Jerry Coffin picture Jerry Coffin · Mar 25, 2011

At least on most machines, a type is only ever aligned to a boundary as large as the type itself [Edit: you can't really demand any "more" alignment than that, because you have to be able to create arrays, and you can't insert padding into an array]. On your implementation, short is apparently 2 bytes, and int 4 bytes.

That means your first struct is aligned to a 2-byte boundary. Since all the members are 2 bytes apiece, no padding is inserted between them.

The second contains a 4-byte item, which gets aligned to a 4-byte boundary. Since it's preceded by 6 bytes, 2 bytes of padding is inserted between v3 and i, giving 6 bytes of data in the shorts, two bytes of padding, and 4 more bytes of data in the int for a total of 12.