effect of free()

Dick Dunn rcd at ico.ISC.COM
Tue Aug 22 10:33:38 AEST 1989


I had written...
[example stuff about freeing storage, then testing a pointer to it]
> >Not true.  The "if" only examines the value of the pointer, not what it
> >points to.  free(ptr) does not modify ptr; it can't.  Assuming the malloc
> >succeeded ... the code as written will work...
> >The trouble will only begin when you try to look at *ptr.

henry at utzoo.uucp (Henry Spencer) duly chastises me:
> Dick, can you cite chapter and verse in X3J11 saying that it is legal to
> examine a pointer which points to freed storage?  If not, I would say that
> you are making an implementation-dependent assumption...

I was making an implementation-dependent assumption.  Or, more to the
point, I was addressing practice rather than theory:  I haven't been able
to find any implementations of C in which freeing storage associated with a
pointer will make an equality test on that pointer--and particularly a test
for NULL--either cause a trap or produce an unexpected result.  I would be
very interested in knowing of such an implementation!

>...On some machines,
> pointers are very special animals, held in special registers that "know"
> that their contents are pointers, and loading a random value into such a
> register can cause trouble even if you don't dereference it...

Yes, but let's be specific.  Some folks (not Henry) have suggested to me
that the problem might occur on a 386.  It doesn't in any implementation
I know of; it wouldn't in any sane implementation because you'll only use
32-bit pointers (to avoid monstrous performance penalties) which are just
offsets and don't affect segments.  Try a 286, where you need a segment and
offset portion, but the problem still doesn't happen because you don't load
a segment register to test the segment portion of a pointer.  Loading a
segment register is incredibly expensive, and you can't test it anyway!  In
fact, this suggests a more general reason why the problem won't occur in
practice:  Placing a pointer in a "special register" which might cause a
trap implies that the pointer is somehow validated; that validation is
likely to be expensive and is unnecessary to the comparison.  Almost all
machines will allow an integer comparison here.  If the pointer is already
in a register, then the compiler (in conspiracy with the OS against the
hardware) must arrange that the register value not cause a trap--including
the case someone else mentioned, where a context switch occurs along the
way and it is necessary to restore the register.  Add to this that you have
to ensure that pointer values which represent one step off the end of an
array (of possibly large elements) are still representable and comparable,
and efficiency will probably force you to be quite generous in values which
will work in pointer comparisons.

>...Whether any
> of them care about whether the pointer points to valid storage is another
> question.  But it's not clear to me that such behavior is ruled out.

It's clear to me that such behavior IS allowed by the standard.  What I
want to know is whether it ever happens in practice.  I assert that it does
not--if only to get someone to tell me off!  (I collect counterexamples:-)
-- 
Dick Dunn     rcd at ico.isc.com    uucp: {ncar,nbires}!ico!rcd     (303)449-2870
   ...Are you making this up as you go along?



More information about the Comp.lang.c mailing list