Sorting dynamic array in a structure with C qsort ()

为君一笑 提交于 2019-12-11 18:07:57

问题


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);
     }

回答1:


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 !!



来源:https://stackoverflow.com/questions/26735839/sorting-dynamic-array-in-a-structure-with-c-qsort

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!