0

I have the following 2 structs:

typedef struct {
  char fullName[40];
  int yearOfBirth;
} Ancestor;

typedef struct {
  Ancestor **ancestor;
  int capacity;
  int size;
} AncestorList;

and I would like to sort the Ancestor elements os the array by yearOfBirth. Here is how I call qsort():

qsort(listOfGreatUncles->ancestor, listOfGreatUncles->size, sizeof(Ancestor), compare); //listOfGreatUncles is a AncestorList struct

and here is my compare procedure:

int compare(const void *s1, const void *s2) {
  Ancestor *a1 = (Ancestor *)s1;
  Ancestor *a2 = (Ancestor *)s2;

  printf("a1 yearOfBirth %d\n", a1->yearOfBirth);
  printf("a2 yearOfBirth %d\n", a2->yearOfBirth);

  return (a1->yearOfBirth - a2->yearOfBirth);
  }
}

Now my output for a1 and a2 are 0. What am I doing wrong?

1 Answer 1

3

The elements in the array are of type Ancestor * and that's what you should use as the operand to sizeof. The pointers given to the comparison function are pointers to the element type cast to void *, hence you cast them back to Ancestor ** and dereference.

qsort(listOfGreatUncles->ancestor, listOfGreatUncles->size, sizeof (Ancestor *), compare);

or the form that always gives the right size if the array itself is properly typed:

qsort(listOfGreatUncles->ancestor, 
      listOfGreatUncles->size, 
      sizeof listOfGreatUncles->ancestor[0],
      compare);

i.e.

qsort(array, length, sizeof array[0], compfunc);

And finally

int compare(const void *s1, const void *s2) {
    Ancestor *a1 = *(Ancestor **)s1;
    Ancestor *a2 = *(Ancestor **)s2;

    printf("a1 yearOfBirth %d\n", a1->yearOfBirth);
    printf("a2 yearOfBirth %d\n", a2->yearOfBirth);

    return (a1->yearOfBirth - a2->yearOfBirth);
}

And the return value should actually be

return (a1->yearOfBirth > a2->yearOfBirth) - (a1->yearOfBirth < a2->yearOfBirth);

to avoid undefined behaviour on extreme values of int.

Sign up to request clarification or add additional context in comments.

1 Comment

a1->yearOfBirth - a2->yearOfBirth may overflow and provide the wrong answer and is UB. return (a1->yearOfBirth > a2->yearOfBirth) - (a1->yearOfBirth < a2->yearOfBirth); nicely handles that. Of course extreme years are not expected, such values may occur as sentinels.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.