Quote:> The following is the code to test byte alignment.
> -------------------------------------------------
> struct m { char c; short s; char c1; } m;
> main() {
> char a[] = {0x11, 0x22, 0x33, 0x44, 0x55};
> struct m *pm = (struct m *)a;
> printf("%x %x %x", pm->c, pm->s, pm->c1); }
> ----------------------------------------------
> In my opinion, the result should be 0x11 0x3322 0x44. However, the result is
> 0x11 0x4433, 0x55. I know it's caused by the word alignment. Can anyone
> pointer me how to resolve this problem? Thanks in advance.
Several folks have pointed out that you should NOT write code
like this. Under standard C/C++ the behavoir is undefined,
and indeed you will find that the behavoir can and will
change from machine to machine. Nevertheless, it's worth
understanding what is going on.
The low level view of your structure, from your results, is
offset 0: char c
offset 1: unused byte (for alignement)
offset 2: address of least significant byte of short s
offset 3: address of most signficant byte of short s
offset 4: addres of char c1
offset 5: unused byte (for alignment)
To see the presence of the 6th byte (at offset 5) print
out the "sizeof(struct m)". You should get "6". Putting
in this extra byte is neccessary in case later you have
an array of struct m's, in order that the "short" always
be alligned on an even byte offset.
This is all *very* machine dependent (on some machines,
this can also be compiler dependent, altough in C the
layout of struct for most machines is specified in
a document called an Application Binary Interface). For example,
while many modern machines will add in unused bytes to obtain the
above alignements, some won't, and others might add in
more bytes to force everything to 32-bit or 64-bit alignment.
Further, the fact that the least signficant byte comes first
suggests that you are working with an Intel-based machine.
Most RISC chips would give the opposite order (most signficant
byte first).
Again, you shouldn't rely upon this behavoir, but it is
worth understanding. In particular, it is worth noting
that if you had defined the
struct m{ char c; char c1; short s };
then on *MANY* machines you would use less space, but
yet you could still write code which would be valid C
on *ALL* machines (assuming you don't do funky things like
at the start of this message :-)).
Best wishes,
Mike