0

I want to know this situation.

when I define this sentence

struct soccer team[100] ; 

I can do qsort ;

qsort(team, MAX , sizeof(team[0]) , compare) ;
int compare(const void *a, const void *b ) 
{
   SOC *A1 =  (SOC*)a ; 
   SOC *B1 =  (SOC*)b ;

   if( A1->score > B1->score )
       return -1 ;
   else if ( A1->score == B1->score )
       return 0 ;
   else
       return 1 ;
}

When I do dynamic allocation

struct soccer*team[MAX] ;
team[Index] = (SOC*)malloc(sizeof(SOC)) ;

error is existed. (qsort and compare is same )

I want to know how do use it(qsort for dynamic allocation struct)

please!

example ( when I use first way)

Man 3 1 1 16
Che 2 2 2 8
Asn 0 6 0 6 
hot 6 0 0 18
City 0 0 6 0 
Bar 1 5 0 8

is converted

hot 6 0 0 18
Man 3 1 1 16
Che 2 2 2 8
Bar 1 5 0 8
Asn 0 6 0 6 
City 0 0 6 0 
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
박기현
  • 15
  • 6
  • "qsort and compare is same" it is bad because the same comparision function shouldn't be used for different element type. – MikeCAT Jul 09 '16 at 14:38
  • [Please see this discussion on why not to cast the return value of `malloc()` and family in `C`.](http://stackoverflow.com/q/605845/2173917). – Sourav Ghosh Jul 09 '16 at 14:41
  • my misstake! original code : typedef struct soccer SOC ; – 박기현 Jul 09 '16 at 15:24

3 Answers3

1

The first version

 struct soccer team[100] ;

and the second one

struct soccer*team[MAX] ;
team[Index] = (SOC*)malloc(sizeof(SOC)) ;

are not same. The first one is an array of struct soccer and the second one is an array of struct soccer *. They are not just the same.

If you want to use the later version (including pointer) and get the same behaviour as above, you can do something like

struct soccer * team;
team = malloc(sizeof *team * SIZE) ;  // SIZE is the number of elements    
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
0

The same comparision function cannot be used for different element types. Use correct comparision function like this (pointers to elements, which are pointers, will be given, so dereference them to get the pointers to structs):

int compare2(const void *a, const void *b ) 
{
   SOC *A1 =  *(SOC**)a ;
   SOC *B1 =  *(SOC**)b ;

   if( A1->score > B1->score )
       return -1 ;
   else if ( A1->score == B1->score )
       return 0 ;
   else
       return 1 ;
}

Note: They say you shouldn't cast the result of malloc() in C.

Community
  • 1
  • 1
MikeCAT
  • 73,922
  • 11
  • 45
  • 70
  • @박기현 Please post a [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) to have us fix it. – MikeCAT Jul 09 '16 at 15:01
0

Here is a demonstrative program that shows how a similar array can be sorted.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define MAX 10

typedef struct soccer
{
    unsigned int score;
} SOC;

int cmp( const void *a, const void *b )
{
    const SOC *lhs = *( const SOC ** )a;
    const SOC *rhs = *( const SOC ** )b;

    return ( lhs->score > rhs->score ) - ( rhs->score > lhs->score );
}

int main( void ) 
{
    SOC * team[MAX];

    srand( ( unsigned int )time( NULL ) );

    for ( int i = 0; i < MAX; i++ ) 
    {
        team[i] = malloc( sizeof( SOC ) );
        team[i]->score = rand() % MAX;
    }       

    for ( int i = 0; i < MAX; i++ ) 
    {
        printf( "%u ", team[i]->score );
    }
    printf( "\n" );

    qsort( team, MAX, sizeof( SOC * ), cmp );

    for ( int i = 0; i < MAX; i++ ) 
    {
        printf( "%u ", team[i]->score );
    }
    printf( "\n" );

    for ( int i = 0; i < MAX; i++ ) free( team[i] );

    return 0;
}

The program output is

2 7 2 5 1 6 1 5 0 4 
0 1 1 2 2 4 5 5 6 7
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335