Help with tsearch (3C) in sysV

Gary S. Moss SLCBR-VLD-V moss at BRL.ARPA
Tue Jul 22 01:30:48 AEST 1986


Herman,
	I wrote my own tsearch(3C) before we got our system V sources, so I
have an opinion of how it is supposed to work, even though I never tried it.
You should not need to define a record type as this is supposed to be trans-
parent to the application.  That is why all pointers are cast to "char *" or
"char **" when passed in to the library.  Your use of key appears correct,
assuming that your strcompar function knows how to order strings and returns
the appropriate values.  Your use of rootp does not seem correct; its hard
to tell since you didn't declare it.  Rootp should be declared as a variable
(some kind of pointer), initialized to NULL, and its address should be passed
in.  Here is an example.

#include <stdio.h>
extern char	*malloc(), *tsearch();
char	*rootp = NULL;
char	line[MAXLINE];
char	*ptr, *datum;
int	strcompar();

	while( fgets( line, MAXLINE, file ) )
		{
		datum = malloc( strlen( line ) + 1 );
		if( datum == NULL )
			{
			(void) fprintf( stderr, "Malloc() no more core.\n" );
			return	1;
			}
		(void) strcpy( datum, line );
		ptr = tsearch( datum, &rootp, strcompar );
		}
The first time through the loop, rootp is NULL indicating to tsearch() that
the tree is empty, and a NULL pointer will be returned indicating the same,
while rootp's contents will be altered to contain the address of the datum
(line) at the new root of the tree.  On subsequent loops, the address of
the datum (line) will be returned by tsearch.  I assume that the datum is
not copied into the tree structure, so you must allocate space for it and
pass its address in, a simple test should confirm this.  If you wish, you
can store more complex data types:

struct rec
	{
	int	key;
	double	xyz[3];
	}
node, *datum, *rootp = NULL, *ptr;

int	compar( datum1, datum2 )
char	*datum1, *datum2;
	{
	return	(struct rec *) datum1->key - (struct rec *) datum2->key;
	}

...
	while( fread( (char *) node, sizeof(struct rec), 1, stdin ) == 1 )
		{
		datum = (struct rec *) malloc( sizeof(struct rec) );
		if( datum == NULL )
			{
			(void) fprintf( stderr, "Malloc() no more core.\n" );
			return	1;
			}
		*datum = node;
		ptr = (struct rec *)
			tsearch( (char *) datum, (char **)&rootp, compar );
		}
...

Be careful when using twalk(), that you pass rootp, NOT ITS ADDRESS.

Good luck,
-moss



More information about the Comp.unix.wizards mailing list