Sorting an array of pointers to struct based on an element inside the struct

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • yassinov
    New Member
    • Apr 2018
    • 4

    Sorting an array of pointers to struct based on an element inside the struct

    Hi everyone . I'm still a beginner in C especially with structures and pointers. So what i want to do here is to sort an Array of pointers to Structs based on a string inside the Struct . All the Element are dynamically allocated . And i want to know how to free the allocated Memory . My code is written in German so i will be writing only the parts that i don't understand in English . thank you in advance I appreciate your help.

    Code:
    typedef struct Vehicle {
    char *manufacturer;
    char *serialnumber;
    int weight;
    };
    void SortByID(struct fahrzeug** data, int Anzahl){
        struct Vehicle *temp= (struct Vehicle*)malloc( sizeof(struct Vehicle) ) ;
        int i =0 ;
        while ( i < Anzahl && strcmp(data[i]->serialnumber, data[i+1]->serialnumber) < 0)
            {
                temp = data[i+1];
                data[i + 1] = person[i];
                data[i]=temp ;
                i++;
            }
        }   
        free(temp);
        temp=NULL;
    }
    int main(){
    struct Vehicle **array = NULL ;
    array=(struct Vehicle**)malloc(  5 * sizeof(struct Vehicle*)  );
    SortByID (  &array, count ) ;
    return 0; 
    }
    and i will be uploading the whole Programme but it is written in German and there is a lot of non complete function in it .
    Attached Files
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    You might read this:




    You create each Vehicle using malloc.

    You load data into each Vehicle.

    You place the Vehicle* for these Vehicle in the array of Vehicle**

    When you are finished with each Vehicle*, you free the pointer.

    The sort just rearranges the Vehicle* in the array. It does not malloc.

    If you have malloc data inside your struct you need to write your own free function that will free the member allocations and then free the struct itself.

    Post again if this does not help.

    Comment

    • yassinov
      New Member
      • Apr 2018
      • 4

      #3
      thank you for replying
      I've tried to sort the array of pointer just by swapping the pointers inside it . it will be easier . i 've used the qsort funtion but without success
      Code:
      int compare(const void *a, const void *b) {
        struct Vehicle * const *one = a;
        struct Vehicle * const *two = b;
      
        return strcmp((*one)->serialnumber, (*two)->serialnumber);
      }
      void SortByID(struct Vehicle** data, int Anzahl){
           qsort( data, Anzahl, sizeof(struct Vehicle*) ,compare );
      }

      Comment

      • weaknessforcats
        Recognized Expert Expert
        • Mar 2007
        • 9214

        #4
        Have you got a clean compile yet?

        This code:
        Code:
        void fahrzeugSortByID(struct fahrzeug** daten, int Anzahl){
            struct fahrzeug *temp= (struct fahrzeug*)malloc( sizeof(struct fahrzeug) ) ;
            for(int i =0 ; i<Anzahl ; i++){
                temp = &(daten[i]);
                daten[i]=&(daten[i+1]);
                daten[i+1] =&temp ;
            }
        has indirection errors. daten is a fahrzeug** so daten[i] is a fahrzeug*. Therefore, &daten[i] is a fahrzeug**. It is being assigned to temp which is a fahrzeug*. My compiler says no-no.

        Also, this is C so you can't assign a struct using the assignment operator =. You have to write a function to make a memberwise copy of each element of the struct.

        This code: temp = &(daten[i]) will destroy the contents of temp which is a pointer to memory allocated by malloc. This memory is now not able to be freed. This is, this is a leak.

        Comment

        • yassinov
          New Member
          • Apr 2018
          • 4

          #5
          thank you for your Healp .I've already found a solution with you Help and the Help of Other Programmer on stackoverflow . I'm still a beginner in c that's why there is a lot that i have to learn. I appreciate your Help
          this is a working version of what i am trying to do

          Code:
          #include <stdio.h>
          #include <stdlib.h>
          #include <string.h>
          
          struct Vehicle {
              char *manufacturer;
              char *serialnumber;
              int weight;
          };
          
          int cmp_serialnumber(const void *p1, const void *p2)
          {
              const struct Vehicle *v1 = *(struct Vehicle * const *)p1;
              const struct Vehicle *v2 = *(struct Vehicle * const *)p2;
          
              return strcmp(v1->serialnumber, v2->serialnumber);
          
          /*
              // Alternatively You could write this function as this less readable one liner
              return strcmp((*(struct Vehicle * const *)p1)->serialnumber,
                              (*(struct Vehicle * const *)p2)->serialnumber);
          */
          }
          
          int cmp_manufacturer(const void *p1, const void *p2)
          {
              const struct Vehicle *v1 = *(struct Vehicle * const *)p1;
              const struct Vehicle *v2 = *(struct Vehicle * const *)p2;
          
              return strcmp(v1->manufacturer, v2->manufacturer);
          }
          
          void print_vehicles(struct Vehicle **vehicles, int n) {
              for (int i=0; i<n; i++) {
                  printf("%s, %s, %d\n", vehicles[i]->serialnumber,
                          vehicles[i]->manufacturer, vehicles[i]->weight);
              }
          }
          
          
          #define N_VEHICLES  5
          char *manufacturers[] = {"McLaren", "Ferrari", "Renault", "Mercedes", "Alfa Romeo"};
          char *serialnumbers[] = {"SN500", "SN4", "SN8", "SN2", "SN1"};
          
          
          int main(){
              struct Vehicle **vehicles = NULL;
          
              vehicles = (struct Vehicle**)malloc(N_VEHICLES * sizeof(struct Vehicle *));
          
              for(int i=0; i<N_VEHICLES; i++) {
                  vehicles[i] = (struct Vehicle *)malloc(sizeof(struct Vehicle));
                  vehicles[i]->manufacturer = manufacturers[i];
                  vehicles[i]->serialnumber = serialnumbers[i];
                  vehicles[i]->weight = 1000;
              }
          
              printf("Before\n");
              print_vehicles(vehicles, N_VEHICLES);
              printf("\n");
          
              // sort by serial number
              qsort(vehicles, N_VEHICLES, sizeof(struct Vehicle *), cmp_serialnumber);
              printf("Sorted by serial number\n");
              print_vehicles(vehicles, N_VEHICLES);
              printf("\n");
          
              // sort by manufacturer
              qsort(vehicles, N_VEHICLES, sizeof(struct Vehicle *), cmp_manufacturer);
              printf("Sorted by manufacturer\n");
              print_vehicles(vehicles, N_VEHICLES);
          
              return 0;
          }

          Comment

          • yassinov
            New Member
            • Apr 2018
            • 4

            #6
            Thank you. you are the only one who helped me here .

            Comment

            Working...