Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!ncar!ico!vail!rcd From: rcd@ico.ISC.COM (Dick Dunn) Newsgroups: comp.lang.c Subject: Re: effect of free() Summary: but does it happen in practice??? Message-ID: <16030@vail.ICO.ISC.COM> Date: 22 Aug 89 00:33:38 GMT References: <319@cubmol.BIO.COLUMBIA.EDU> <3756@buengc.BU.EDU> <1989Aug18.185011.26836@utzoo.uucp> Organization: Interactive Systems Corp, Boulder, CO Lines: 56 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@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@ico.isc.com uucp: {ncar,nbires}!ico!rcd (303)449-2870 ...Are you making this up as you go along?