Home > Enterprise >  Sorting an Array of Struct with type Char, qsort
Sorting an Array of Struct with type Char, qsort

Time:11-01

I am running into a zsh: segmentation fault (this error has to do with memory) I have no idea as to why it is occurring. I am trying to make a compare function for the string in my struct. I need the program to be able to sort through the strings in ascending order.

Current Code:

#include <stdio.h>
#include <string.h>
#include "stdlib.h"
# define MAX 7

typedef struct{
    double price;
    char title[60];
} game;
game gArr[MAX];

game buildGame(double num, const char *title);
void printGame(game);

int compGamesByTitle(const void * a,const void * b);

int main(){
    gArr[0] = buildGame(0.01, "Minecraft");
    gArr[1] = buildGame(22.79 , "Opus Magnum");
    gArr[2] = buildGame(7.79 , "TIS-100");
    gArr[3] = buildGame(14.99 , "Trainz");
    gArr[4] = buildGame(0 , "Code Combat");
    gArr[5] = buildGame(7.79, "Lemmings Revolution");
    gArr[6] = buildGame(64.96 , "Warcraft");

    qsort(gArr,sizeof(gArr)/sizeof(gArr[0]), sizeof(gArr[0]), compGamesByTitle);
    printf("Sorted Games:\n");
    for (int i = 0; i < MAX; i  ){
        printGame(gArr[i]);
    }


    return 0;
}
int compGamesByTitle(const void *a,const void *b){
    char **aa = (char **)a;
    char **bb = (char **)b;

    return strcmp(*aa,*bb);
}

game buildGame(double num, const char *title){
    game g;
    g.price = num; strcpy(g.title, title);
    return g;
}
void printGame(game g){
    printf("Game g: %.2f, %s\n", g.price, g.title);
}

I think the problem has to do with un-allocated memory but I'm not sure where or why.

Required Output: Strings in the array of structs should be sorted alphabetically (a-z) in ascending order.

CodePudding user response:

No, your problem is not related to uninitialized memory. The comparison function passed as the fourth argument of qsort receives pointers to the array elements that are being compared. Since your gArr is an array of game object, but you are casting to char** inside the compGamesByTitle you end up calling strcmp on pointers that do not point at null-terminated byte strings, invoking undefined behavior.

Your comparison function should really look like this

int compGamesByTitle(const void *a,const void *b){
    const game *aa = a;
    const game *bb = b;

    return strcmp(aa->title, bb->title);
}

CodePudding user response:

This is not an answer to the question but just som additional input to @UnholySheep answer.

The

game buildGame(double num, const char *title){
    game g;
    g.price = num; strcpy(g.title, title);
    return g;
}

Should be more robust again long title names. Suggesting

game buildGame(double num, const char *title) {
    game g;
    g.price = num;
    g.title[0] = '\0';
    strncat(g.title, title, sizeof(g.title) - 1U);
    return g;
}

as long as game::title remains an array.

The use of strncat over strncpy is motivated by not writing more characters than necessary.

  • Related