[comp.unix.wizards] Why doesn't this qsort example work?

sean@ms.uky.edu (Sean Casey) (10/19/87)

I'm trying to use qsort(3) for the first time and I'm having a bit of
trouble.  I've included some code here that reproduces the problem.
The following C program coredumps because compar() is being called with
bogus arguments.  I'm sure it's my fault, but I just can't seem to see
what I'm doing wrong.  Maybe one of you can tell me:

struct tstr {
	int a;
	int b;
};

compar(x, y)
struct tstr *x, *y;
{
	if (x->a < y->a)	/* coredumps here, therefore a or b is bogus */
		return(-1);	/* a < b */
	if (x->a > y->a)
		return(1);	/* a > b */
	return(0);		/* a = b */
}

main()
{
	struct tstr t[2];

	t[0].a = 1;
	t[1].a = 2;
	/* this sorts t[] by the "a" field */
	qsort(&t[0], 2, sizeof(struct tstr), (*compar)());
}


Thanks for any light you can shed,

Sean

-- 
--  Sean Casey               sean@ms.uky.edu, {rutgers,uunet,cbosgd}!ukma!sean
--  (the Empire guy)         sean@ms.uky.csnet,  sean@UKMA.BITNET
--  "Have fun storming the castle!" - Miracle Max

gwyn@brl-smoke.ARPA (Doug Gwyn ) (10/19/87)

In article <7527@g.ms.uky.edu> sean@ms.uky.edu (Sean Casey) writes:
!struct tstr {
!	int a;
!	int b;
!};
!compar(x, y)
!struct tstr *x, *y;
	char *X, *Y;			/* replaces the above line */
!{
	struct tstr *x = X, *y = Y;	/* inserted new line */
!	if (x->a < y->a)	/* coredumps here, therefore a or b is bogus */
!		return(-1);	/* a < b */
!	if (x->a > y->a)
!		return(1);	/* a > b */
!	return(0);		/* a = b */
!}
!main()
!{
!	struct tstr t[2];
!	t[0].a = 1;
!	t[1].a = 2;
!	/* this sorts t[] by the "a" field */
!	qsort(&t[0], 2, sizeof(struct tstr), (*compar)());
	/* replace the above line with the following: */
	qsort((char *)&t[0], (unsigned)2, sizeof(struct tstr), compar);
!}

eric@ms.uky.edu (Eric Herrin) (10/19/87)

>sean@ms.uky.edu (Sean Casey) writes:
>
>I'm trying to use qsort(3) for the first time and I'm having a bit of
>trouble.  I've included some code here that reproduces the problem.
>The following C program coredumps because compar() is being called with
>bogus arguments.  I'm sure it's my fault, but I just can't seem to see
>what I'm doing wrong.  Maybe one of you can tell me:
>	qsort(&t[0], 2, sizeof(struct tstr), (*compar)());


Hmm... It seems to me you have a couple of things confused...

1. The qsort 'compar' argument is a pointer to a function, thus you send it
   a pointer to a function (you seem to have put the declaration in the
   parameter list).
2. You are really sending qsort(3) an integer in that field, since compar()
   returns an integer.  Not only that but you are calling compar in the
   parameter list with no parameters (thus you believe compar is getting
   bogus arguments, which it is since you aren't sending any...).

The correct statement would be something like:

	qsort((char *)&t[0], 2, sizeof(struct tstr), compar);

which will send the ADDRESS of compar() and not the value the function
returns.  Hope this helps....

				eric


-- 
|    Eric Herrin II				     	cbosgd!ukma!eric      |
|    "'tis better to be silent                         	eric@UKMA.BITNET      |
|     and be THOUGHT a fool, than to open              	eric@ms.uky.csnet     |
|     one's mouth and remove all doubt."                eric@ms.ukFrom: Juam Oct

ark@alice.UUCP (10/19/87)

In article <7527@g.ms.uky.edu>, sean@ukma.UUCP writes:
 
> I'm trying to use qsort(3) for the first time and I'm having a bit of
> trouble.  I've included some code here that reproduces the problem.

> 	/* this sorts t[] by the "a" field */
> 	qsort(&t[0], 2, sizeof(struct tstr), (*compar)());

Try

	qsort(&t[0], 2, sizeof(struct tstr), compar);

As you wrote it, you're calling compar with no arguments.
Presto, instant core dump!

boykin@custom.UUCP (Joseph Boykin) (10/20/87)

In article <7527@g.ms.uky.edu>, sean@ms.uky.edu (Sean Casey) writes:
> 
> I'm trying to use qsort(3) for the first time and I'm having a bit of
> trouble.

...Bunch of stuff deleted...

> 	qsort(&t[0], 2, sizeof(struct tstr), (*compar)());

The fourth (last) argument to qsort is the address of the function
which will do the comparison.  What you've done here is to *call*
the function 'compar' without any arguments and the return value
of that function call would be passed to qsort.  The function isn't
core dumping because of bogus values of 'a' as you stated, but
because the pointers 'x' and 'y' within the function were using
whatever garbage values were left over on the stack.  The correct
call to qsort would be:

 	qsort(&t[0], 2, sizeof(struct tstr), compar);
-- 

Joe Boykin
Custom Software Systems
...necntc!custom!boykin