Re: malloc() and alignment



Eric Sosman <esosman@xxxxxxxxxxxxxxxxxxx> writes:
Francine.Neary@xxxxxxxxxxxxxx wrote:
[...]
I'd say the situation would be greatly improved by having eg three
types of allocation function:
1) malloc, generic allocator, same as current malloc
2) malloc_char, returns a pointer only guaranteed to be aligned for
char
3) malloc_int, same but for int.
Is there a good reason something like this isn't in the Standard? And
no implementations seem to have a facility like this either.

[...]

One thing you'll probably discover is that malloc() often
reserves a little more space than is requested, space in which
it can park some housekeeping data. That data typically takes
at least as much space as a size_t, perhaps more. It's surely
most convenient if the housekeeping data itself is properly
aligned, which in turn influences the alignment of the entire
inflated chunk. And if you already need alignment sufficient
for a size_t, it's usually no hardship to provide "strictest"
alignment.

Also, back when malloc() was first designed, it's likely that the
strictest alignment requirement possible was just 2 bytes, or maybe 4
(think PDP-11 and friends), so malloc()'s alignment requirement
wouldn't have wasted much space.

[...]

Long ago, c.l.c. debated whether malloc(1) needed to provide
memory that was properly aligned for double, say, in the common
situation where sizeof(double)>1. One side stuck to the letter
of the Standard: the returned value had to be properly aligned
for any type, and that was that. The other side pointed out that
any attempt to store a double in the 1-byte region would invoke
undefined behavior anyhow, hence no strictly conforming program
could run afoul of looser alignment for small allocations; the
difference made no difference. If I recall correctly, the strict
Standard constructionists carried the day, but it was more due
to volume than to virtue.

Another argument in that debate is that just assigning a misaligned
pointer value invokes undefined behavior. For example, this:

void *ptr = malloc(1);
assert(ptr != NULL);
double *dptr = ptr;

must work properly; dptr's value must be distinct from the address of
any double object, and you must be able to detect this using "==" or
"!=". If assigning a misaligned pointer value to a double* causes a
trap, this implies that the result of malloc(1) must be properly
aligned.

If, on the other hand, assigning a misaligned pointer value to a
double* doesn't cause a trap (until you try to dereference it), then
an implementation could get away with having malloc(1) return a
misaligned pointer; it arguably would violate the standard, but the
violation would be difficult to detect.

--
Keith Thompson (The_Other_Keith) kst-u@xxxxxxx <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
.