[comp.lang.c] question about free

vander@nssdcb.gsfc.nasa.gov (John Vanderpool) (08/01/90)

does the free() function return anything?
in VAXC v3.0 it's defined as:  void free (void *ptr);

i though it used to (just to tell you it was successful)
  - was that an incorrect implementation ?

if the argument is void *ptr how does it know how many bytes to release?
which brings me to my example (attached) do i need to cast the pointer
before free()ing it?

thanx, hope this isn't too stupid!

				fish

------------------------------------------------------------------------------

/* each type of XAB is a different size structure on VAX/VMS for unix folks */

#include xab

#define NULL (void *) 0


void RMS_free_XABchain( struct XABKEY *xabp )

	/* originally had as void *xabp but then you can't reference its
			elements */
{

	/* cast XAB pointer using XAB type code in xab$b_cod */

	switch( xabp->xab$b_cod )
	{
	  case XAB$C_ALL : xabp = (struct XABALL *) xabp;  break;
	  case XAB$C_DAT : xabp = (struct XABDAT *) xabp;  break;
	  case XAB$C_FHC : xabp = (struct XABFHC *) xabp;  break;
	  case XAB$C_KEY : xabp = (struct XABKEY *) xabp;  break;
	  case XAB$C_PRO : xabp = (struct XABPRO *) xabp;  break;
	  case XAB$C_RDT : xabp = (struct XABRDT *) xabp;  break;
	  case XAB$C_SUM : xabp = (struct XABSUM *) xabp;  break;
	  case XAB$C_TRM : xabp = (struct XABTRM *) xabp;  break;
	  default : printf( "bad xab code=%d\n", xabp->xab$b_cod );  return;

	}	/* end switch */


	/* recursively call until end of chain is reached, free on unwind */

	if( xabp != NULL )
	{
	  RMS_free_XABchain( xabp->xab$l_nxt );
	  free( xabp );
	}

}	/* RMS_free_XAB_chain */

karl@haddock.ima.isc.com (Karl Heuer) (08/01/90)

In article <2958@dftsrv.gsfc.nasa.gov> vander@nssdcb.gsfc.nasa.gov writes:
>does the free() function return anything?

No.

>in VAXC v3.0 it's defined as:  void free (void *ptr);
>i though it used to (just to tell you it was successful)
>  - was that an incorrect implementation ?

Since free() cannot fail unless the program is already seriously broken,
there's not much point.  It might as well use abort() to flag the error.

>if the argument is void *ptr how does it know how many bytes to release?

Magic.  (I mean that seriously.)  It's not something the user needs to be
concerned with; the implementation will remember the size somehow.

>which brings me to my example (attached) do i need to cast the pointer
>before free()ing it?

You should be okay as long as `free()' has been declared with a prototype.
(It's sufficient to #include <stdlib.h> if your compiler is ANSI-compliant.)
On a compiler without prototypes, you should cast the argument to `char *' (or
`void *' if you have it, but this is also an ANSI invention) for complete
portability.  (It looks like *this* code will never be ported off a vax
anyway, but it's good programming practice, and makes lint happy.)

>void RMS_free_XABchain( struct XABKEY *xabp )
>/* originally had as void *xabp but then you can't reference its elements */

If this is a pointer to a generic class of structs that all share a common
initial member, you could use `void *xabp' and reference the common member
with `((struct XABKEY *)xabp)->xab$b_cod'.

>	  case XAB$C_ALL : xabp = (struct XABALL *) xabp;  break;

This almost certainly isn't what you want.

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