Search code examples
cstructtypedefqsort

qsort with typedef structs in C


After searching in lots of posts, I cannot solve my problem. I want to order an array of structs depending on one field (deadline):

typedef struct{
    int ident;
    int computation;
    int period;
    int deadline;
}task_t;
task_t *tasks;

int compare(const void *a, const void *b) {

        task_t *ia = *(task_t**)a;
        task_t *ib = *(task_t**)b;
        //task_t *ia = (task_t *)a;
        //task_t *ib = (task_t *)b;

        return (ia->deadline - ib->deadline);
}

//Randomly generation of parameters of tasks

fprintf(stderr,"before:\n");
    for (i=0;i<nT;i++){
            fprintf(stderr,"%d;%d;%d;%d\n", tasks[i].ident, tasks[i].computation, tasks[i].deadline,tasks[i].period);
        }

size_t size = sizeof(tasks) / sizeof(task_t*);

qsort(tasks, size, sizeof(task_t *), compare);


    fprintf(stderr,"\after:\n");
    for (i=0;i<nT;i++){
            fprintf(stderr,"%d;%d;%d;%d\n", tasks[i].ident, tasks[i].computation, tasks[i].deadline,tasks[i].period);
        }

Before and after qsort, the result is the same. I think the problem is the pointer but I don't know how to solve it. I have tried a lot of combinations qsort(&tasks, size, sizeof(task_t *), &compare); and also inside compare function, but the result does not change. Could you help me? Sorry if the question is so many repeated.


Solution

  • size_t size = sizeof(tasks) / sizeof(task_t*);
    

    only works if tasks is an array of task_t*. It isn't, it's a pointer to task_t (presumably to an array of task_t, but not one with compile-time size). You can't use sizeof in that case, you just have to know how big the array is in some other way. As is, you basically asked qsort to sort an array with one element in it.

    You've also written your comparator wrong; if the array is of task_ts, then the void*s it receives are really pointers to task_t, not double pointers to task_t. So you'll need to change:

        task_t *ia = *(task_t**)a;
        task_t *ib = *(task_t**)b;
    

    to:

        const task_t *ia = a;
        const task_t *ib = b;
    

    Lastly, you need to pass sizeof(task_t) to qsort, not sizeof(task_t *); again, the array is of task_t, not task_t*.