Thread: qsort not sorting structs

  1. #1
    Registered User
    Join Date
    Sep 2010
    Posts
    37

    qsort not sorting structs

    Okay, so all I'm trying to do is use qsort to sort integers in a structure.
    It runs and compiles but doesn't sort. Instead it sets the first 3 ages to 0 and does nothing with the rest. I'm guessing it has to do with what I'm passing to qsort.



    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    
    
    struct constestants
    {
       int age;
       char *name;
    };
    
    int sort(const void *a, const void *b);
    
    int main() {
    
       int i;
       struct constestants *mystruct;
    
       //printf("%d\n", sizeof(struct constestants));
       /*allocates 10 structs for constestants*/
       mystruct = calloc(10,sizeof(struct constestants));
       if (mystruct == NULL) {
          printf("\nAllocation Error");
          exit(1);
       }
    
       /*generate random age*/
       srand(time(NULL));
       for(i=0;i<10;i++) {
          mystruct[i].age = 18 + rand() % 30;
          printf("%d = %d\n", i, mystruct[i].age);
       }
       
       qsort(mystruct, 10, sizeof(mystruct), sort);
    
       printf("\n");
       for(i=0;i<10;i++) {
          printf("%d = %d\n", i, mystruct[i].age);
    
       }
    
       return 0;
    }
    
    int sort(const void *a, const void *b)  {
       /*this gives me the same results as return(*(int*)a - *(int*)b);
          it clears the first 3 ages and does nothing else*/
       /*
        if(*(int*)a > *(int*)b)
          return 1;
        if(*(int*)a < *(int*)b)
          return -1;
    
        return 0;
       */
    
       
       /*----this method doesn't seem to work
        struct contestants *id1 = (struct contestants *)a;
        struct contestants *id2 = (struct contestants *)b;
        if(*(int*)id1->id > *(int*)id2->id)
          return 1;
        if(*(int*)id1->id < *(int*)id2->id);
          return -1;
       return 0;
       */
    
        return(*(int*)a - *(int*)b);
    }

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    The third argument of qsort needs to be sizeof(struct contestants) not sizeof(mystruct) (which is equivalent to sizeof(struct contestants *)).

    In the sort() function, you would be better off converting a and b into pointers to struct contestants
    Code:
        return ((struct contestants *)a)->age - ((struct contestants *)b)->age;
    The fact your sort function happens to work is a fortunate accident.

    It is confusing to, as you have done, to name a pointer as if it is a struct.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  3. #3
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    You compare function (called sort) does not compare the ages in your structs, instead it casts the addresses of the structs to int pointers and dereferences them (which does not make any sense at all).

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Too big typos hamstrung you on this one.

    Code:
    qsort(mystruct, 10, sizeof(mystruct), sort);
    The other one is a little more subtle and explains why "this method doesn't seem to work" -- your original spelling was constestants. But that is the proper way to go (cast to type and compare the appropriate fields). You're doing some wacky stuff with trying to cast some non-existent member (id1->id) as an int pointer or something there tho too. Sort() should look like this:

    Code:
    int sort(const void *a, const void *b)  {
    	struct constestants *id1 = (struct constestants *)a;
    	struct constestants *id2 = (struct constestants *)b;
    
    	if (id1->age > id2->age) return 1;
    	return -1;
    }
    That, and correct the typo in the qsort() call.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    Registered User
    Join Date
    Sep 2010
    Posts
    37
    Thank you all so much. I was working on this last night and it's been a long, long weekend. Haha.
    I'm also not very strong with pointers and structures, thus why I am doing this little project.

  6. #6
    Registered User
    Join Date
    Sep 2010
    Posts
    37
    I have another question with qsort and the compare function.
    I know I can make two compare functions that will sort in ascending and descending order. Is there a way to make it conditional so I can have both in one compare function? I tried passing an int that corresponds to 2 different options into the compare function, and as expected, it didn't work.
    Right now, I'm just printing out the results in reverse.

  7. #7
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    The comparison functions don't sort. They compare two values. That is why they are described as comparison functions.

    What is wrong with having two distinct comparison functions? If they could somehow be merged into one function, how would you expect the caller to specify the required behaviour (or operating mode, or whatever)?
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 3
    Last Post: 03-31-2009, 12:34 PM
  2. Can I use STL qsort() for sorting structure?
    By franziss in forum C++ Programming
    Replies: 14
    Last Post: 09-20-2005, 05:34 AM
  3. sorting a linked list with qsort()
    By caduardo21 in forum C Programming
    Replies: 12
    Last Post: 04-19-2005, 08:08 PM
  4. qsort not sorting
    By sweets in forum C Programming
    Replies: 3
    Last Post: 08-08-2004, 04:46 AM
  5. Sorting a list of structs
    By Jan79 in forum C++ Programming
    Replies: 9
    Last Post: 06-24-2003, 01:42 AM