简体   繁体   中英

C qsort array of nested structs

I'm trying to sort an array of struct records. For some reason a core dump keeps occuring.

When I try doing the same thing with an array of ints or structs, it works perfectly fine. However when I start using nested structs, it begins to core dump.

The current output is:

Before sorting
first last 0  
first last 1  
first last 2  
first last 3  
first last 4  
first last 5  

AFTER sorting  
Segmentation fault (core dumped)

Compiler: Cygwin

typedef struct {
    char last[NAMESIZE]; /* last name (1 word) */
    char first[NAMESIZE]; /* first name (1 word) */
} name;

typedef struct {
    name name;
    int score; /* score (between 0 & 100 inclusive) */
} record;

int compare (const void * a, const void * b){
    const record *recordA = (record *)a;
    const record *recordB = (record *)b;
    printf("%d: %d", recordA->score, recordB->score);
    return ( recordB->score - recordA->score );
}

int main (){
    record ** list;
    int i;
    list=malloc(6*sizeof(record*));
    printf("Before sorting\n");
    for(i=0; i<6; i++){ 
        list[i]=malloc(sizeof(record));
        strcpy(list[i]->name.first,"first");
        strcpy(list[i]->name.last,"last");
        list[i]->score=i;   
    }
    for (i=0; i<6; i++){
        printf ("%s %s %d\n",list[i]->name.first, list[i]-    >name.last,list[i]->score);         
    }

    printf("AFTER sorting\n");
    qsort (list, 6, sizeof(record), compare);
    for (i=0; i<6; i++){
        printf ("%s %s %d\n",list[i]->name.first, list[i]- >name.last,list[i]->score);         
    }    
  return 0;
}

list is an array of 6 pointers to record :

list=malloc(6*sizeof(record*));

so you need to pass the same size to qsort .

qsort (list, 6, sizeof(record), compare);

should be

qsort (list, 6, sizeof(record*), compare);

or better yet

qsort (list, 6, sizeof(*list), compare);

I'm agree with the first answer.But one thing clear is that you should not use qsort (list, 6, sizeof(record), compare) , in which sizeof(record) will return the total bytes of record but do not automatically count the bytes used by the name. nor qsort (list, 6, sizeof(record), compare) , in which sizeof(record) will return the 4 bytes of record*,since it's a pointers. Instead, I think maybe you just need count the bytes by your self and add another data,like namesize, in your data structure record

If you have a comparison function for two records, you want to assign them to a pointer to a constant that points to a record.

In your qsort, I'm guessing you've passed in your record list data structure, so the number of elements will be your nused.

/*Comparison function: Score ascending only.*/
int cmp_sasc(const void *p, const void *q){
    record * const *pp = p;
    record * const *qq = q;
    return (*pp)->score - (*qq)->score;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM