Reputation: 8476
I have the following struct:
struct foo
{
int a;
char b;
};
It is stored to memory and pointer to it can be unaligned (odd address).
So, is this safe?:
const struct foo a = *((struct foo*)char_ptr);
I am worrying, because the integer member of the source struct can be in odd address. In some systems reading of (multi byte) integer from odd adderess causes problems.
EDIT:
For avoiding off-topic commenting about usage of const
, I did remove a const
from the code. (I never cast const pointer to non-const pointer, even in this case where it should not cause any problems)
And more about context of problem:
This kind of structure is part of protocol frame. And it can be in any offset inside the frame. In the real code the struct have __attribute__((packed))
attribute. But that probably not change the answer?
Anyway, I could use memcopy
and non-const a
for solving the problem. But I would like to use the assingment, because it seems to be more elegant way (if it is safe).
Upvotes: 2
Views: 642
Reputation: 223702
No, it is not safe, unless you know the pointer has the alignment required for the structure.
Here are some ways to know the pointer has the necessary alignment:
malloc
) that guarantees the address returned is suitably allocated for any use (which malloc
does guarantee).uintptr_t
and test its alignment, provided this is supported by your C implementation.If you do not know the pointer has the necessary alignment, then you should not access the structure through a converted pointer. Instead, you can define a new structure and use memcpy
to copy from the pointer-to-char into the new structure.
Upvotes: 1
Reputation: 20402
If you get your data from a source where the pointer to the data isn't necessarily aligned, the only safe thing you can do is memcpy and hope that your complier isn't "smart" and pretends that the misaligned pointer is actually aligned and the memcpy can be optimized (there are several older versions of gcc that have this bug, requiring you to write a custom memcpy function that's not called memcpy). Depending on you architecture you can get away with improperly aligned access, but it will almost certainly be slower, sometimes even emulated through kernel traps.
A side anecdote: This is usually a problem in network stacks in operating systems where the odd size of the ethernet header makes the IP header unaligned and if the hardware doesn't have the ability to misalign the received packets (some DMA engines can only write data on 4 byte boundaries), this requires the whole headers (or the whole packet) to be copied once more in software.
Upvotes: 1
Reputation: 20980
See Data structure padding. On most systems, the structure will be aligned & internal member addresses will be aligned wrt their respective sizes, while malloc'ing itself.
If you manually create a memory pool & use some section within that to store your struct object, then compiler will not guarantee you alignment, but if you use malloc to create the struct object, it is generally compiler's headache, to give you aligned addresses, with padding if required between struct elements.
Upvotes: 2