ошибка сегментации fread чтение базы данных из двоичного файла на c

#c

Вопрос:

Я пишу функцию, которая помогает мне читать базу данных книг из двоичного файла. Однако при использовании fread у меня возникает ошибка сегментации.

Это та функция, о которой я говорю.

 Array *readdb (FILE *db, Array *ind) {  Array *database = NULL;  Book *book = NULL;  indexbook *indentry;  char *buffer, bytesdepillar = 0, titprintby[MAX_ENTRADA];  int reader = 0;   if (db == NULL || ind == NULL)   return NULL;   database = malloc(sizeof(Array));   initArray(database, INIT_ARR_SIZE);   fseek(db, 0L, SEEK_END);  bytesdepillar = ftell(db)/sizeof(char);  fseek(db, 0, SEEK_SET);  buffer = malloc(bytesdepillar * sizeof(char));  fread(buffer, sizeof(char), bytesdepillar, db);    for (size_t i = 0; i lt; ind-gt;used; i  ) {  book = malloc(sizeof(Book));  indentry = (indexbook*) ind-gt;array[i];   reader = indentry-gt;offset;   book-gt;bookID = indentry-gt;key;  reader =sizeof(int);  memcpy(book-gt;ISBN, amp;buffer[reader], ISBN_LEN);  reader =ISBN_LEN;  memcpy(titprintby, amp;buffer[reader], indentry-gt;offset   indentry-gt;size - reader);  strcpy(book-gt;title, strtok(titprintby, "|"));  strcpy(book-gt;printedBy, strtok(NULL, "|"));    insertArray(database, book);  }   return database; }  

ind-это индекс базы данных со следующей структурой:

 typedef struct {  int key;  long int offset;  size_t size;  } indexbook;   

Файл открывается с помощью

 if ((dbf = fopen(db_name, "rb")) == NULL) {  fclose(indf);  printf("%s does not exist", db_name);  return 1;  }   

Комментарии:

1. Не имеет отношения к вашей проблеме, но sizeof(char) (или любой другой тип, основанный на char ) указан как всегда 1 . Вам никогда не нужно умножать или делить на это.

2. Что касается вашей проблемы, вы пытались использовать отладчик , чтобы поймать сбой? Когда и где в вашем коде это происходит? Каковы значения всех задействованных переменных в момент и в месте аварии?

3. chmod -r $db_name; ./a.out $dm_name приводит к замечательному сообщению об ошибке «$db_name не существует». Файл действительно выходит, но у пользователя нет разрешения на его чтение. Никакое сообщение об ошибке вообще не лучше, чем неправильное сообщение об ошибке. man perror

4. indentry не инициализируется.

5. @Someprogrammerdude Я использовал gdb, чтобы проверить, где происходит ошибка сегментации. Это происходит в следующей строке: fread(buffer, sizeof(char), bytesdepillar, db);

Ответ №1:

Как вы уже заявили в разделе комментариев, когда строка

 fread(buffer, sizeof(char), bytesdepillar, db);  

выполняется, переменная bytesdepillar имеет отрицательное значение.

Поскольку вы объявили переменную типа char , в зависимости от вашей платформы, она, вероятно, может представлять значения только между -128 и 127 . Если вызов to ftell возвращает значение , превышающее 127 значение, оно, вероятно (что именно происходит, определяется реализацией), будет преобразовано в значение между -128 и 127 . Это, скорее всего, причина, по которой это отрицательное значение.

Поэтому я рекомендую вам изменить объявленный тип bytesdepillar с char на long , который является типом , возвращаемым функцией ftell .

Если после изменения объявленного типа на long значение продолжает оставаться отрицательным, то это , вероятно, связано с ftell возвращением функции -1 из-за сбоя функции. В этом случае вы должны убедиться, что db это относится к допустимому потоку (например, убедитесь, что файл был успешно открыт).

Комментарии:

1. Верно, я не заметил, что объявил это как символ, большое спасибо