Alignment determines where the addresses will be, not how much space they will take.
A char
only takes up 1 byte, even if it is aligned on an 8 byte boundary. There are 6 unused bytes between c1 and c2.
Often, the alignment and the size will be the same, or the alignment is rounded up to a power of 2. That's because on many architectures it may require multiple FETCH instructions to retrieve from a non-aligned memory address.
In your case, c1
is aligned on a 1-byte boundary, so it is placed at the first available position on the stack.
c2
is aligned on an 8-byte boundary, so it skips over however many bytes are needed until the address is aligned on an 8 byte boundary. This means (address % 8) == 0. If c2
were of type double
, it would need to move to the next aligned address, 8 more bytes ahead, but since it is only a char
it fits just fine at the first 8-byte boundary. (EDIT: as others have pointed out, the compiler could rearrange the variables, and probably would in that case)
The alignment can be greater or less than the size of the element.
On some architecture, you simply HAD to align on 2 or 4 byte boundaries. The computers simply could not address the "in between bytes". The address lines aren't needed, so you can address 2^16 bytes of memory using only 14 address lines if you align on 4 byte addresses (and always read 4 bytes). That can reduce the size needed for the memory bus.