Common malloc/free practice violates ANSI standard ?

Scott A. Rotondo scott at altos86.Altos.COM
Mon Oct 16 11:56:43 AEST 1989


In article <1989Oct14.043811.669 at anucsd.oz> bdm at anucsd.oz (Brendan McKay)
asserts that the pANS does not permit this code:

         OBJ *objptr;

         objptr = (OBJ*)malloc( sizeof(OBJ) );
         ...
         free( (void*)objptr );

> malloc() returns a value of type void*, "suitably aligned so that it
> may be assigned to a pointer to any type of object and then used to
> access such an object..." (Section 4.10.3).  Thus, it is clear that we
> may use the value assigned to objptr without worry.  The trouble comes
> with the call to free(), who's argument must "match a pointer earlier
> returned by the [malloc] function".

> Consider the following hypothetical implementation:
> * pointers are implemented as memory addresses in the common way
> * objects of type OBJ require even addresses.
> * assigning a void* to an OBJ* involves rounding up to an even address
> * malloc allocates sufficient space so that it will cover an object of
>   type OBJ even when the void* value returned is rounded up to even.
>   (Thus, sometimes it actually allocates one more cell than it is asked for.)
> * assigning an OBJ* to a void* involves no change of address

Your hypothetical implementation is not Standard-conforming because of
the fourth point above.  Your quote from section 4.10.3 requires that
the pointer returned from malloc() be aligned according to the most
restrictive alignment requirements for this implementation.  That means
that the cast from void * to OBJ * must leave the address unchanged
(the internal pointer representation may change, but that is
invisible).  Similarly, the cast from OBJ * to void * will not change
the address.

> This implementation is unusual, but seems to obey the rules.  There was no
> requirement that malloc() return an even address, only that the value
> returned could be used after casting to OBJ*.  However, when objptr is cast
> back to void* for passing to free(), the value obtained is possibly different
> from the one returned by malloc(), thus breaking the rules for free().

As indicated above, malloc() must return an even address in this
implementation.  Since neither cast will change the address, free()
will work as expected.

> No doubt this problem was unintentional.  It could easily be fixed by a
> sentence reading something like "The pointer returned if the allocation
> succeeds is such that, if it is cast to a pointer to any type of object
> and then that pointer is cast to type void*, the original value is
> recovered."

This is precisely the meaning of the section 4.10.3 alignment rule.
-- 
===============================================================================
Scott A. Rotondo, Altos Computer Systems			 (408) 946-6700

{sun|pyramid|uunet}!altos86!scott				scott at Altos.COM	



More information about the Comp.std.c mailing list