fread分割故障从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 < ind->used; i++) {
book = malloc(sizeof(Book));
indentry = (indexbook*) ind->array[i];
reader = indentry->offset;
book->bookID = indentry->key;
reader+=sizeof(int);
memcpy(book->ISBN, &buffer[reader], ISBN_LEN);
reader+=ISBN_LEN;
memcpy(titprintby, &buffer[reader], indentry->offset + indentry->size - reader);
strcpy(book->title, strtok(titprintby, "|"));
strcpy(book->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;
}

正如您在注释部分所述,当行

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

则变量bytesdepillar具有负值。

由于您声明变量的类型为char,根据您的平台,它可能只能表示-128127之间的值。如果对ftell的调用返回的值高于127,则它可能(具体发生的情况由实现定义(会转换为-128127之间的值。这很可能是它为负值的原因。

因此,我建议您将bytesdepillar的声明类型从char更改为long,这是函数ftell返回的类型。

如果在将声明的类型更改为long之后,该值继续为负,则可能是由于函数ftell由于函数失败而返回-1。在这种情况下,您应该验证db是否引用了有效的流(例如,验证文件是否已成功打开(。