0

I have a problem to sort an array (dynamically allocated) in a structure. Firstly, the idea was to order the array i in the structure in an ascendant order. Then I was thinking to order the array i maintaining instead the array j with the same "relationship" obtained when it was constructed the initial structure. I try to work for the first idea, but without any result with qsort.So this is my code... Any ideas? I think there is a problem in the construction of the comparing function..

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

int M =10;
int N =30;
int K = 10;

struct element {
int *i;
int *j;
int k;  
};

struct element *create_structure();
void print_element(struct element *);
int compare (const void *, const void * );
struct element * sort(struct element *);


main()
{
     srand(time(NULL));
     struct element *lista;
     int count;
     lista=create_structure();
     print_element(lista);
     printf("\n");
     lista=sort(lista);
}


 struct element *create_structure()
 {
         int aux1,aux2,count,load;
         struct element *structure;
         structure = (struct element *) malloc (M*sizeof(struct element *));
         structure->k=K;
         structure->i= (int *)malloc(structure->k*sizeof(int));
         structure->j=(int *)malloc (structure->k*sizeof(int));
            for (count = 0; count < K; count ++)
            {
               aux1=rand()%N;
               (structure->i)[count]=aux1;
                  do
                  {
                  aux2=rand()%N; 
                  }while(aux2==aux1);
               (structure->j)[count]=aux2;
            }
  return (structure);   
   }

   void print_element(struct element *lista)
   {
      int count;
      for(count = 0; count < K; count ++)
      {
         printf("%d     %d\n",lista->i[count],lista->j[count]);
      }
   }



   int compare(const void *a, const void *b)
     {
        struct element *ia = (struct element *)a; 
         struct element *ib = (struct element *)b; 
         int *ptr1=(ia->i);
         int *ptr2=(ib->i);
     return (*ptr1-*ptr2); 
     }


    struct element * sort(struct element *list)
     {
       qsort(list, sizeof(list->i)/ sizeof(int) , sizeof(list->i), compare);
      //qsort(list->i, K, sizeof(list->i), compare);
      print_element(list); 
      return (list);
     }
Andres
  • 1
  • 1
  • How to order the array i of the structure with qsort()? – Andres Nov 04 '14 at 13:08
  • Each call to create_structure allocates some memory to your structure and fills in values for the members, so if you want to do it this way then you should have linked list to hold all values then sort them – Gopi Nov 04 '14 at 13:24

1 Answers1

0

Sorry for being late to the party ! :)

So let's start first by mentioning the wrong statements in your code

>> First

in function create_structure() you want to allocate memory for your structure pointer

struct element *structure; // here your structure pointer is 
//pointing to memory space of type struct element

structure = (struct element *) malloc (M*sizeof(struct element *));
                                       |------------------------|
                                                    |
                                                    V
Here you are allocating memory space of type struct element* which is 
wrong ! instead it must be sizeof(struct element)

Concerning the while loop in the same function I found that it is totally useless

aux1=rand()%N;
(structure->i)[count]=aux1; // the value is in aux1 variable 
do
 {
      aux2=rand()%N; 
 }while(aux2==aux1); // the loop try to get the same value of aux1 
                     // or you have just stored it in aux1
(structure->j)[count]=aux2; // it is easy to delete the while loop and
                            // change aux2 by aux1

>> Second

Concerning the sort

qsort(list, sizeof(list->i)/ sizeof(int) , sizeof(list->i), compare);
     |-----|
        |
        V
It is not an adress of the array so it is Wrong !

after knowing the major problems here is a version of code based on your own code which works perfectly

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

int M =10;
int N =30;
int K = 10;

struct element {
    int *i;
    int *j;
    int k;
};

struct element *create_structure();
void print_element(struct element *);
int compare (const void *, const void * );
void sort(struct element *); // changed the return value of sort
// to void as the argument will be changed directly because it is a
// pointer 


int main()
{
    srand(time(NULL));
    struct element *lista;
    lista=create_structure();
    printf("\n--------- i ---  j  ---------\n\n");
    print_element(lista);
    printf("\n---------------------------\n");

    sort(lista);
    print_element(lista);
    return 0;

}


struct element *create_structure()
{
    int aux1=0,count=0;
    struct element *structure;
    // Changed the allocation of structure pointer 
    structure = (struct element *) malloc (sizeof(struct element));
    structure->k=K;
    structure->i= (int *)malloc(K*sizeof(int));
    structure->j=(int *)malloc (K*sizeof(int));
    for (count = 0; count < K; count ++)
    {
        aux1=rand()%N; 
        // we kept only the first aux1 and copied it in the two arrays
        (structure->i)[count]=aux1;
        (structure->j)[count]=aux1;
    }
    return (structure);
}

void print_element(struct element *lista)
{
    int count=0;
    for(count = 0; count < K; count++)
    {
        printf("row=%2d :  %2d     %2d\n",count+1,(lista->i)[count],(lista->j)[count]);
    }
}


int compare(const void *a, const void *b)
{
    // compare the values of two case of array pointed by i of type int
    return *(int*)a-*(int*)b;
}


void sort(struct element *list)
{
  // we will sort the array pointed by i which contains K elements 
  // of type int and size sizeof(int) by using the compare function
    qsort(list->i, K , sizeof(int), compare);
}

Hope it helps ! :)

Note: Using this code in codeblocks v13.12 generates under linux (gcc version 4.8.2) wrong output !! [ It might be a BUG in Code::Blocks] but using it with command line with gcc gives correct output !!