C does not guarantee that the least significant bit is zero only if the pointer is aligned for all possible types. In practice, the 2 or 3 least significant bits are likely to be zero, but do not count on it.
You can see for yourself, but the best way is to use something like posix_memalign .
If you want to do this yourself, you will need to swap memory and track the original pointer. Something like (assuming you want 16-byte alignment, you can make it generic, not verified):
void * my_aligned_malloc16 (size_t sz) {
void * p = malloc (sz + 15 + 16); // 15 to ensure alignment, 16 for payload
if (! p) return NULL;
size_t aligned_addr = ((size_t) p + 15) & (~ 15);
void * aligned_ptr = (void *) aligned_addr;
memcpy (aligned_ptr, & p, sizeof (void *)); // save original pointer as payload
return (void *) (aligned_addr + 16); // return aligned address past payload
}
void my_aligned_free16 (void * ptr) {
void ** original_pointer = (void **) (((size_t) ptr) - 16);
free (* original_pointer);
}
As you can see, this is pretty ugly, so prefer to use something like posix_memalign . Perhaps your runtime has a similar function if it is not available, for example. memalign (thanks @R ..) or _ aligned_malloc when using MSVC.
user786653
source share