pointers & order of execution

Karl Heuer karl at haddock.ima.isc.com
Wed Jun 21 03:27:51 AEST 1989


In article <844 at cbnewsl.ATT.COM> dfp at cbnewsl.ATT.COM (david.f.prosser) writes:
>Any use of the value of t after the realloc call causes undefined behavior.

This is an important point, which I completely ignored in my own followup
(which was concerned with the order-of-evaluation question).  Clearly it's
meaningless to attempt to dereference a |free|'d pointer (including the old
value of a |realloc|'d pointer); but what's not as well known is that you
can't reliably do *anything* with that value anymore -- not even copy it into
a new variable, or compare it with |NULL|.

This allows for an implementation on a segmented architecture to have |malloc|
allocate a new segment from the system, and |free| return it.  If the hardware
distinguishes between arithmetic registers and address registers, and if
loading a bogus segment address into an address register causes a hardware
trap, then bad things could happen if the user does anything with a |free|'d
pointer.  So, in order to not place an undue burden on such implementations,
the pANS labels this as undefined behavior.

Hence, the correct way to synchronize mid-array pointers is:
	/* |b| is a |malloc|'d buffer; |c| points somewhere inside */
	something  *oldb = b;
	ptrdiff_t   dist = c - b;
	if ((b = (something *)realloc((void *)b, newsize)) == NULL) {
		b = oldb;  /* oldb is still valid, since |realloc| failed */
		fprintf(stderr, "sorry, no more space\n");
	} else {
		c = b + dist;
	}

Karl W. Z. Heuer (ima!haddock!karl or karl at haddock.isc.com), The Walking Lint



More information about the Comp.std.c mailing list