You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言使用fread读取二进制图书数据库文件出现段错误

段错误引发原因
  • 变量类型定义错误:存储文件大小的bytesdepillar被定义为char类型,ftell返回的是long类型的文件偏移量,只要文件大小超过char的取值范围(通常最多255字节)就会发生溢出,导致malloc申请的buffer空间远小于实际需要,后续fread或者访问buffer时直接越界触发段错误。
  • 内存分配未校验返回值:database、buffer、book的malloc调用都没有检查返回值,一旦内存分配失败返回NULL,后续对空指针的读写操作直接触发段错误。
  • 偏移量类型不匹配:存储读取偏移的reader被定义为int类型,而indexbook的offset是long int类型,当文件偏移超过int的取值范围时reader溢出,导致访问&buffer[reader]时越界。
  • 字符串处理非法:memcpy向titprintby拷贝内容后没有手动加字符串结束符\0,strtok要求操作对象是合法的\0结尾的字符串,会越界读取栈内存触发段错误;同时如果拷贝长度超过MAX_ENTRADA会直接栈溢出。
  • 野指针拷贝:如果Book结构体的title、printedBy是未分配内存的char*指针,直接调用strcpy向野指针地址写入内容会直接触发段错误;同时未判断strtok的返回值,如果条目不存在|分隔符,strtok返回NULL,传入strcpy也会触发段错误。
修复方案
  1. 修正变量类型,避免溢出
// 原定义:char *buffer, bytesdepillar = 0, titprintby[MAX_ENTRADA]; int reader = 0;
// 修改为:
char *buffer, titprintby[MAX_ENTRADA];
long bytesdepillar = 0; // 用long存储文件大小
long reader = 0; // 用long匹配offset的类型
  1. 所有内存分配后校验返回值,避免空指针访问
database = malloc(sizeof(Array));
if (database == NULL) return NULL;
initArray(database, INIT_ARR_SIZE);

// ...

buffer = malloc(bytesdepillar * sizeof(char));
if (buffer == NULL) {
    free(database);
    return NULL;
}
fread(buffer, sizeof(char), bytesdepillar, db);

for (size_t i = 0; i < ind->used; i++) {
    book = malloc(sizeof(Book));
    if (book == NULL) continue; // 或根据业务需求做错误处理
    // ...
}
  1. 规范字符串处理逻辑,避免溢出和非法访问
size_t copylen = indentry->offset + indentry->size - reader;
// 限制拷贝长度不超过titprintby的最大容量,预留结束符位置
if (copylen >= MAX_ENTRADA) copylen = MAX_ENTRADA - 1;
memcpy(titprintby, &buffer[reader], copylen);
titprintby[copylen] = '\0'; // 手动添加字符串结束符

// 校验strtok返回值
char *title = strtok(titprintby, "|");
char *printedBy = strtok(NULL, "|");
if (title == NULL || printedBy == NULL) {
    free(book);
    continue;
}
// 若Book的title、printedBy是指针,需要先分配内存再拷贝
book->title = malloc(strlen(title) + 1);
book->printedBy = malloc(strlen(printedBy) + 1);
if (book->title == NULL || book->printedBy == NULL) {
    free(book->title);
    free(book->printedBy);
    free(book);
    continue;
}
strcpy(book->title, title);
strcpy(book->printedBy, printedBy);

内容的提问来源于stack exchange,提问作者federicoporritos84

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 08:54:05