http://stackoverflow.com/questions/...nment-in-c-interview-question-that-stumped-me
In this link there is explanation of
how to get aligned memory for malloc.
I don't understand how this is valid:
if (ptr) free(((void**)ptr)[-1]);
It might not be. Looking at the web page that you cited, the relevant
code that sets ptr has many serious problems:
void *ptr = ((char*)mem+sizeof(void*)+15) & ~ (size_t)0x0F;
The left operand of the unary & operator is a pointer. That's a
constraint violation: "Each of the operands shall have integer type."
(6.5.10p2). The only requirement on a conforming implementation of C
when processing such code is that it must generate at least one
diagnostic message. After doing so, it is free to generate an
executable; if it does, you are free to run the executable, but the
behavior when it runs is undefined.
If an implementation supports uint_ptr_t (which is optional), then
uintptr_t temp = (uintptr_t)(((char*)mem+sizeof(void*)+15) & 0x0F;
would produce a number satisfying:
temp % 16 == 0
temp/16 == (uintptr_t)((char*)mem+sizeof(void*)+15)/16
Which is probably precisely what that author expected would be the
result of his bitwise-and expression. As a result, that person probably
expected that ptr would 16 byte aligned
ptr >=(char*)mem+sizeof(void*)
ptr <= (char*)mem+sizeof(void*) + 15
On many implementations, all of those expectations will be met. But
there is no justification in the C standard for any of those
expectations (even if you use the uintptr_t approach). All that the C
standard says about the result of that conversion is that "the result is
implementation-defined, might not be correctly aligned, might not point
to an entity of the referenced type, and might be a trap
representation." (6.3.2.3p5)
It would have been perfectly legal to use ptr = (void**)mem + 1, and if
that had been done, then
if (ptr) free(((void**)ptr)[-1]);
would have been perfectly safe. The only problem it that it doesn't
necessarily meet the specification, which requires that ptr be 16-byte
aligned.
The original question, of producing a pointer that is 16-byte aligned,
has no portable solution. malloc() is required to return a pointer
correctly aligned for any type, so on systems where achieving 16-byte
alignment actually matters, a simple call to malloc() is sufficient,
there's no need to do any fiddling with the result. On other systems,
there's no portable way to compute such a pointer, but also no
legitimate need to do so.
In C2011, the _Alignas() alignment specifier was provided, so you could
answer part a) with:
{char _Alignas(16) array[1024];
and answer part b) with:
}
However, there is a constraint on the argument of _Alignas(): "The
constant expression shall be an integer constant expression. It shall
evaluate to a valid fundamental alignment, or to a valid extended
alignment supported by the implementation in the context in which it
appears, or to zero." (6.7.5p3). A fundamental alignment is one that is
less than or equal to _Alignof(max_align_t). (6.2.8p2). On an
implementation where _Alignof(max_align_t) < 16, it's implementation
defined whether 16 is a valid extended alignment; if it's not, the
_Alignas() approach is also a constraint violation.