Получение ошибки сегментации при чтении из файла - PullRequest
2 голосов
/ 29 апреля 2020

Я имею дело со структурами и указателями на символы (строки). Я хочу создать массив структур, и эти структуры имеют char* и два int s.

Я получаю ошибку сегментации при попытке fscanf в array и struct с.

Вот соответствующая часть моего кода.

Struct Def

typedef struct {
    char* title;
    int gross;
    int year;
} Movie;

Функция У меня возникают проблемы с

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;

}

Чтобы добавить это в случае необходимости, вот как я вызываю функцию

        Movie* arr = createArray(file1, records);

1 Ответ

2 голосов
/ 29 апреля 2020

title - неинициализированный указатель, вам также нужно зарезервировать для него память или просто объявить title как char array с желаемым размером, если это вариант.

Есть некоторые другие проблемы Мне хотелось обратиться к вашей функции, некоторые из которых вы, возможно, знаете, код ниже с комментариями.

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