Yes the behavior is well-defined.
As per the C Standard You need to pass the exact same address to deallocation function free
as was returned by an malloc
or other allocation functions.
Reference:
7.22.3.3 The free function
Synopsis:
§1 #include <stdlib.h> void free(void *ptr);
Description:
§2 The free function causes the space pointed to by ptr to be deallocated, that is, made
available for further allocation. If ptr is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by a memory management
function, or if the space has been deallocated by a call to free or realloc, the
behavior is undefined.
So, In this case the behavior is guaranteed to be well defined if and only if pointer to the structure is same as pointer to it's first member.
And that is guaranteed by the standard in:
6.7.2.1 Structure and union specifiers
§15
Within a structure object, the non-bit-field members and the units in which bit-fields
reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed
padding within a structure object, but not at its beginning.