Consider an array struct foo foos[2] of two struct foo aligned to 2 * sizeof (struct foo) or greater. Observe that foos[0] is aligned to 2 * sizeof (struct foo) or greater whereas foos[1] is only aligned to sizeof (struct foo) . You can use that information to find out if a random struct foo* that points into such an aligned struct foo[2] points to the first or the second member.

To get sufficiently aligned memory, either write a custom allocator or use the C11 aligned_alloc function. Note that it is not really required to have the memory fully aligned, merely having the bit we test in other_half cleared is sufficient.

A naïve implementation of a function to find the other half of a pair of struct foo given a pointer to one half looks like this:

struct foo *other_half(struct foo *half) { if ((uintptr_t)half % (2 * sizeof *half) == 0) return half + 1; else return half - 1; }

This function however is not very efficient if sizeof (struct foo) is not a power of two as it involves a slow modulo operation. To speed things up, consider the factorization of sizeof (struct foo) which is of the form 2n · q. It is easy to see that it is sufficient to check ((uintptr_t)half & (uintptr_t)1 << n) == 0 because 2 * sizeof (struct foo) is a multiple of 2n + 1 and therefore has the bits in positions 0 to n turned off.

Computing n at compile time is a bit tricky, but luckily we only need 1 << n , which can be computed with a little bit magic as -sizeof (struct foo) & sizeof (struct foo) :