I try to sort a struct below, given an intention to sort their error rate, while retaining the information of sid and did. While there is no compilation error, I get a seg fault in runtime. I wonder what has gone wrong….
#include <stdio.h>
#include <stdlib.h>
struct linkdata {
int sid;
int did;
double err;
};
typedef struct linkdata LD;
typedef int (*qsort_func_t)(const void *, const void *);
static int compareByErr (const void * a, const void * b)
{
fprintf(stderr, "aerr=%.3f, berr=%.3f\n", (*(LD**)a)->err, (*(LD**)b)->err);
int aerr = (*(LD**)a)->err;
int berr = (*(LD**)b)->err;
return aerr - berr;
}
int main() {
int idx;
int numnode;
struct linkdata* perr;
qsort_func_t qsort_func = compareByErr;
numnode = 3;
perr = (LD*) malloc (numnode*numnode*sizeof(LD));
perr[0].sid = 0; perr[0].did = 1; perr[0].err = 0.642;
perr[1].sid = 0; perr[1].did = 2; perr[1].err = 0.236;
perr[2].sid = 0; perr[2].did = 3; perr[2].err = 0.946;
idx = 3;
qsort(perr, idx, sizeof(perr), compareByErr);
int i;
for (i=0; i<idx; i++){
fprintf(stderr,"err[%d][%d] = %.3f\n", perr[i].sid, perr[i].did, perr[i].err);
}
free(perr);
}
There are many errors in the code.
1. compareByErr
The
aandbparameters of thecompareByErrfunction are objects ofLD*, notLD**. You did an unnecessary dereferencing. Try to change that function to:2. compareByErr
There is another problem, that you implicitly convert the
doubleintoint. Since all those “errors” are 0.???, they will all be truncated to 0. Making the whole array unsorted. Change it to:3. malloc
You are allocating for 32 nodes, but only 3 are needed. Change that to
4. qsort
The 3rd argument is the size of each element of the array, not
sizeof(perr)which is just the size of a pointer (4 bytes). Change that line to:to actually get the element size.
The
idxseems unnecessary. You could just usenumnodehere.