Conversion between pointer types produces incorrectly aligned result

suggest change

The following might have undefined behavior due to incorrect pointer alignment:

char *memory_block = calloc(sizeof(uint32_t) + 1, 1);
uint32_t *intptr = (uint32_t*)(memory_block + 1);  /* possible undefined behavior */
uint32_t mvalue = *intptr;

The undefined behavior happens as the pointer is converted. According to C11, if a conversion between two pointer types produces a result that is incorrectly aligned (6.3.2.3), the behavior is undefined. Here an uint32_t could require alignment of 2 or 4 for example.

calloc on the other hand is required to return a pointer that is suitably aligned for any object type; thus memory_block is properly aligned to contain an uint32_t in its initial part. Then, on a system where uint32_t has required alignment of 2 or 4, memory_block + 1 will be an odd address and thus not properly aligned.

Observe that the C standard requests that already the cast operation is undefined. This is imposed because on platforms where addresses are segmented, the byte address memory_block + 1 may not even have a proper representation as an integer pointer.

Casting char * to pointers to other types without any concern to alignment requirements is sometimes incorrectly used for decoding packed structures such as file headers or network packets.

You can avoid the undefined behavior arising from misaligned pointer conversion by using memcpy:

memcpy(&mvalue, memory_block + 1, sizeof mvalue);

Here no pointer conversion to uint32_t* takes place and the bytes are copied one by one.

This copy operation for our example only leads to valid value of mvalue because:

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:



Table Of Contents