Search code examples
cpointersstructqsortpointer-to-pointer

qsort on dynamic array of dynamic structs


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?


Solution

  • 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.