Exactly...you definitely need to worry about alignment issues here, even more than endianess. A traditional hack would be to union it with something like a long int* to guarantee alignment, but there's probably a better way to handle this than arrays. Typically, you would malloc the memory (which has guaranteed alignment for all types).
could you please explain that ?
When you just say:
char a[];
you are not guaranteed the the address of a (i.e. the first byte of the array) is aligned on any memory boundary. For example, lets say you particular processor has a 32 bit word size (4 bytes). Addresses that are aligned on a word boundary are things like:
0
4
8
128
2048
16
etc etc...multiples of 4.
Addresses that are not aligned on word boundaries are:
2
7
13
22
etc etc...NOT multiples of 4.
Now what happens when you take an array of characters that happens to start on address 7, for example, and cast it to an int? I don't know either. It depends on your processor. Some processors will deal with it and simply take a performance hit. Other processors assume that 32 bit operations are aligned on 32 bit boundaries, and they can do silly things like simply ignoring the first two bits of the address.
See, what goes on behind the scenes is that often times processors are optimized to work very efficiently on certain size quantities, like a 32 bit word, and even if all you want is a character, you may just get all 32 bits anyway that then get thrown away unused. On the flip side, if it knows it's operating on a word (because your compiler made the call to do 32 bit math instead of 8 bit math), it can make a lot of simplifying assumptions to get much better performance. This comes at the cost of flexibility. In other words, you'd better not call 32 bit functions on misaligned data because the results you get will be highly dependent on really esoteric details of your compiler, linker and processor.
I hope that makes sense. Stuff like this doesn't come up too often just in normal programming, but it comes up a lot anytime you need to interface with the outside world (files, sensors, other embedded thingamabobs) because data often come in as characters or some other inconvenient size.
memcpy() is theoretically always safe if I recall correctly, but in practice compilers will often replace this with a call to an optimized version...which assumes things like word aligned data. You really need to be careful when using datatype smaller than the word size and then casting away type. Once you cast it away to something else (typically int* or void*), you're totally on your own and you have to worry about this stuff.
edit:
So this is why I suggested malloc() or a union with an int. Malloc() guarantees proper alignment for ALL types...sometimes it just allocates on page boundaries (explains why you can sometimes run out of memory with malloc() when you actually have TONS of memory left, you think). If you do a union, you are guaranteed proper alignment for the biggest type in the union.