Xref: utzoo comp.std.c:1824 comp.lang.c:22878 Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!gem.mps.ohio-state.edu!apple!altos!altos86!scott From: scott@altos86.Altos.COM (Scott A. Rotondo) Newsgroups: comp.std.c,comp.lang.c Subject: Re: Common malloc/free practice violates ANSI standard ? Message-ID: <3678@altos86.Altos.COM> Date: 16 Oct 89 01:56:43 GMT References: <1989Oct14.043811.669@anucsd.oz> Reply-To: scott@altos86.UUCP (Scott A. Rotondo) Followup-To: comp.std.c Organization: Altos Computer Systems, San Jose, CA Lines: 56 In article <1989Oct14.043811.669@anucsd.oz> bdm@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@Altos.COM