0

I have the following struct

struct FOO {
    int x;
    double y;
}

and the array

FOO **manyfoos;
manyfoos = malloc( 10 * sizeof(FOO *) );

After this manyfoos is filled with dynamically allocated FOO * elements

manyfoos[i] = malloc( sizeof(FOO) );
manyfoos[i]->x = x;
manyfoos[i]->y = y;

I now want to sort manyfoos with qsort() and the following compare function

int foocmp(const void * p, const void * q) {
    const FOO * pp = (const FOO *)p;
    const FOO * qq = (const FOO *)q;

    return qq->x - pp->x;
}

Unfortunately the following command is giving unexpected results (qq->x and pp->x are random weird numbers).

qsort(manyfoos, 10, sizeof(FOO *), foocmp);

How can I make this work as expected?

2
  • Your comparator is given const void * values that are 'really' const FOO ** values, not const FOO * values. If you sort an array of int, the comparator is given int * (cast to const void *). You're sorting an array of FOO *; therefore, you are given const FOO ** values cast to const void *. Commented Jun 6, 2018 at 23:40
  • See also My qsort comparison function causes strange stuff in memory. Commented Jun 6, 2018 at 23:45

1 Answer 1

0

Well, your comparison-function is off.

The arguments it gets are pointers to the elements in the array qsort() tries to sort, so pointers to FOO*.

The fixed comparison-function is:

int foocmp(const void * p, const void * q) {
    const FOO* const * pp = p;
    const FOO* const * qq = q;

    return (*qq)->x - (*pp)->x; // Beware of overflow / underflow
}

I also left out the superfluous casts.

As an aside, avoid sizeof(TYPE). Use sizeof expr instead, so you don't repeat the type scattered all over your code.

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.