effect of free()

Blair P. Houghton bph at buengc.BU.EDU
Mon Aug 14 14:09:01 AEST 1989


In article <319 at cubmol.BIO.COLUMBIA.EDU> ping at cubmol.UUCP (Shiping Zhang) writes:
>
[...mallocs space; assigns pt1 to point to it...]
>
>pt2=pt1;
>
>then if free() is called using ONE of the points, say pt1, as its 
>argument, is the space pointed by pt1 really freed?

Yes.  It can now be allocated to something else.  It is _not_,
however, cleared or otherwise overwritten by free(), nor are
any pointers into it deallocated or overwritten.

>First, can pt2 still be used as a valid point?  In other words,
>is pt2 still pointing to the location it is assigned to? 

Yes, it points there; but, the data is not guaranteed to be valid.  The
exception is if these pointers are actually stored in the block of
allocated memory into which they also point.  Their life is over.
Until their (sizeof long) bytes are reallocated to some other purpose
and overwritten, you could still dereference them.  Note, however, that
the only way to have a pointer inside the block is if you have, outside
the block, already allocated a pointer to that pointer.

Nobody ever said data-structures was easy... :-)

>My answer to this question SEEMS yes according to some tests I made.

No intervening [mc]alloc()'s, no problem.  You have only your
conscience to maintain.

>Second, would the space still pointed to by pt2 be reallocated
>by other calls to calloc() or other similar funtions?

Yes.  pt2 is as gone as pt1 is.  Which is to say, pt2 and pt1
are still there, but they point to unreliable things.

Programming tip:

It might be prudent to have a spare pointer to the beginning of the
allocated space expressly for the purpose of using that pointer in
a call to free(), since any other pointers (those used for data
processing) may be changed and never set back to their origin.
Prudent, if not economical; you rarely have a situation where none
of the pointers is already used to be the origin for offsets.

I'd do it in linked-list applications where the data is accessed by
routines that find the ends of lists by entries in the nodes.  I keep a
pointer to the original node, and a pointer to the origin of the data
block.  The original node may be removed from the list, and one of the
child nodes will become the new root for the list.  Now there is
obviously a need to maintain that pointer to the origin of the
dynamically-allocated block of memory, regardless of the use to which
the rest of the memory is put, or wherever any other pointers point.

>According to the document I read about free(), the space pointed
>by the argument to free() is made available for further allocation,
>though its contents are left unchanged. But it does not say what will
>happen to the other points pointed to the same space.

Leave it to the manual to be inadequate... Leave it to me to
obfuscate its inadequacy... :-)

The block originally allocated had a size (the size you specified).
That block is a unit.  When you make a call to free() using a pointer
to that block, the entire unit becomes free to be allocated again.  No
pointer that points into that block can be guaranteed to point to what
it pointed to before you free()'d the block, (although it certainly
points to the place that thing used to be).  This is true especially
if you know there is a [mc]alloc() between the free() and the
use of the pointer, and especially if the recent allocation
required less area than was freed.

				--Blair
				  "free(advice);"



More information about the Comp.lang.c mailing list