Q: Why is my compiler leaving holes in structures, wasting space and preventing ``binary'' I/O to external data files? Can I turn this off, or otherwise control the alignment of structure fields?
A: Many machines access values in memory most efficiently when the values are appropriately aligned. (For example, on a byte-addressed machine, short ints of size 2 might best be placed at even addresses, and long ints of size 4 at addresses which are a multiple of 4.) Some machines cannot perform unaligned accesses at all, and require that all data be appropriately aligned.
Therefore, if you declare a structure like
struct { char c; int i; };the compiler will usually leave an unnamed, unused hole between the char and int fields, to ensure that the int field is properly aligned. (This incremental alignment of the second field based on the first relies on the fact that the structure itself is always properly aligned, with the most conservative alignment requirement. The compiler guarantees this alignment for structures it allocates, as does malloc.)
Your compiler may provide an extension to give you control over the packing of structures (i.e. whether they are padded or not), perhaps with a #pragma (see question 11.20), but there is no standard method.
If you're worried about wasted space, you can minimize the effects of padding by ordering the members of a structure based on their base types, from largest to smallest. You can sometimes get more control over size and alignment by using bit-fields, although they have their own drawbacks. (See question 2.26.)
See also questions 2.13, 16.7, and 20.5.
Additional links:
A bit more
explanation of ``alignment''
and why it requires paddding
Additional
ideas on working with alignment and padding
by Eric Raymond,
couched in the form of six new FAQ list questions
Corrections to the above from
Norm Diamond
and
Clive Feather
References:
K&R2 Sec. 6.4 p. 138
H&S Sec. 5.6.4 p. 135