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