简体   繁体   中英

C: Using qsort to sort an array of pointers to an ADT (struct)

I've been trying to use qsort() to sort an array of pointers of an ADT (named SSET ), but I'm getting a weird result. Here's my function:

extern void sset_sort_sets(SSET *sets[], int n) {
    qsort(sets, n, sizeof(SSET *), sset_cmp);
}

In sset_cmp() , I put a statement to print out the SSET s it is comparing.

int sset_cmp(const void *a, const void *b){
    SSET *pa = (SSET *) a;
    SSET *pb = (SSET *) b;

    printf("sset_cmp called:\n");
    printf("  a = "); sset_display(pa);
    printf("  b = "); sset_display(pb);
    printf("\n");

    // More stuff...

I created an array of two SSET s (in main() )

SSET *s[2];
int a[] = {-4, 0, 3, 3, 22};
int c[] = { 1, 2, 3, 4, 5};
s[0] = sset_from_array(c, n); // { 1 2 3 4 5 }
s[1] = sset_from_array(a, n); // { -4 0 3 22 }

int i;
printf("Before sort:\n");
for (i = 0; i < 2; i++)
    sset_display(s[i]);
printf("\n");

sset_sort_sets(s, 2);

printf("After sort\n");
for (i = 0; i < 2; i++)
    sset_display(s[i]);

But here is what I get in the output:

Before sort:
  { 1 2 3 4 5 }
  { -4 0 3 22 }

sset_cmp called:
  a =   { -1589621936 -4 0 3 22 }
  b =   { -1589621568 }

After sort
  { 1 2 3 4 5 }
  { -4 0 3 22 }

I think I'm messing something up with the pointers in calling qsort() , but I'm not sure how.

I think I included all of the related code. Tell me if there's any other segments you need to find my mistake.

SSET *pa = (SSET *) a;

looks wrong. qsort passes pointers to the elements to the comparison function. Your array elements are pointers, so your comparison function receives pointers to pointers:

SSET *pa = *(SSET **)a;

qsort() passes a pointer to the array elements into the comparison function. So, if you have an array of int , the comparison function will receive int * .

You are attempting to sort an array of pointers to SSET , that is, an array of SSET * . Thus, the comparison function will receive pointers to pointers to SSET (so, SSET ** ).

So you need to change this:

SSET *pa = (SSET *) a;
SSET *pb = (SSET *) b;

To:

SSET *pa = *(SSET **) a;
SSET *pb = *(SSET **) b;

Also, it is usually a good idea not to hardcode a typename as the operand of sizeof . If the type changes, it is another place you'll have to update in the future, and you might make mistakes because you have to remember to use the correct type.

Consider changing this line:

qsort(sets, n, sizeof(SSET *), sset_cmp);

To:

qsort(sets, n, sizeof(sets[0]), sset_cmp);

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