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.