To expand slightly on KennyDM's excellent answer (Kenny - please do steal this to supplement your answer if you want), this is probably what your memory structure looks like once the compiler has aligned all of the variables:
0 1 2 3 4 5 6 7
+-------------------+----+-----------+
| i | ch | (unused) |
+-------------------+----+-----------+
8 9 10 11 12 13 14 15
+-------------------+----------------+
| p | (unused) |
+-------------------+----------------+
16 17 18 19 20 21 22 23
+------------------------------------+
| d |
+------------------------------------+
So, because of the 3-byte gap between "ch" and "p", and the 4 byte gap between "p" and "d", you get a 7 byte padding for your structure, thus the size of 24 bytes. Since your environment's double
has 8-byte alignment (i.e. it must reside in it's own block of 8-bytes, as you can see above), the entire struct
will also be 8-byte aligned over-all, and so even re-ordering the variables will not alter the size from 24 bytes.