Reputation: 41
I am dealing with structures and char pointers (strings). I want to make an an array of structures and those structures have a char*
, and two int
s.
I am getting a segmentation fault when attempting to fscanf
into the array
and struct
s.
Here is the relevant part of my code.
Struct Def
typedef struct {
char* title;
int gross;
int year;
} Movie;
Function I am heaving issues with
Movie* createArray(char *filename, int size)
{
FILE *f;
f = fopen(filename, "r");
Movie* arr = (Movie*) malloc(sizeof(Movie) * size);
if(!arr){printf("\nAllocation Failed\n"); exit(1);}
for (int i =0; i<size; i++){
fscanf(f, "%s %d %d", (arr+ i)->title, &arr[i].gross, &arr[i].year);
}
fclose(f);
return arr;
}
To add on to that in case it is needed here is how I call the function
Movie* arr = createArray(file1, records);
Upvotes: 2
Views: 83
Reputation: 23822
title
is an uninitialized pointer, you will also need to reserve memory for it, or simply declare title
as a char array
with desired size if that's an option.
There some other issues I felt like addressing in your function, some of them you might be aware of, code below with comments.
Movie* createArray(char *filename, int size)
{
FILE *f;
if(!(f = fopen(filename, "r"))){ //also check for file opening
perror("File not found");
exit(EXIT_FAILURE); //or return NULL and handle it on the caller
}
//don't cast malloc, #include <stdlib.h>, using the dereferenced pointer in sizeof
//is a trick commonly used to avoid future problems if the type needs to be changed
Movie* arr = malloc(sizeof(*arr) * size);
if(!arr) {
perror("Allocation Failed"); //perror is used to output the error signature
exit(EXIT_FAILURE);
}
for (int i =0; i<size; i++) {
if(!((arr + i)->title = malloc(100))){ // 99 chars plus null terminator,
perror("Allocation failed"); // needs to be freed before the array
exit(EXIT_FAILURE); //using EXIT_FAILURE macro is more portable
}
//always check fscanf return, and use %99s specifier
//for 100 chars container to avoid overflow
if(fscanf(f, "%99s %d %d", (arr+ i)->title, &arr[i].gross, &arr[i].year) != 3){
exit(EXIT_FAILURE); //or return NULL and handle it on the caller
}
}
fclose(f);
return arr;
}
Upvotes: 2