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

C语言同进程可读写二进制文件,单独读取时触发段错误求助

问题拆解与解决方案

这个问题我太熟悉了,你踩了二进制文件读写里的两个经典坑——结构体内存分配错误和指针序列化的误区,咱们一步步理清楚:

1. 首先是致命的内存分配错误

看你代码里的这行:

new = (details *)malloc(sizeof(new));

这里new是details*类型的指针,sizeof(new)拿到的是指针本身的大小(64位系统里是8字节,32位是4字节),而不是details结构体的完整大小!这就导致你只分配了一小块内存,后续给new->num和new->name赋值时,大概率会触发内存越界,为后续的段错误埋下隐患。

正确的写法应该是分配结构体的大小:

new = (details *)malloc(sizeof(details));

2. 核心问题:字符串指针的二进制写入无效

你结构体里的char *name是个指针,当你用fwrite直接写入整个结构体时,写入的只是指针存储的内存地址,而不是指针指向的字符串内容。

  • 同一程序流程里读取时,这个地址还在当前进程的地址空间里,所以能正常访问到字符串;
  • 但单独启动程序读取时,这个地址已经不属于当前进程的有效内存(甚至可能是内核空间),直接访问就会触发段错误。

两种解决思路

思路一:用固定大小字符数组代替指针

如果你的字符串长度是可预估的,直接把结构体改成固定数组的形式,这样字符串内容会直接存在结构体里,读写都不用额外处理:

typedef struct Details {
    int num;
    char name[256]; // 根据需求调整大小,确保能容纳最长的字符串+终止符
} details;

这种方式最简单,适合大多数场景。

思路二:手动序列化字符串(适合动态长度字符串)

如果必须用指针,那就要分开写入结构体的非指针部分、字符串长度和字符串内容,读取时反向操作:

修正后的写入函数
int writeData(char *filename, details *data) {
    FILE *fp = fopen(filename, "wb");
    // 先写入num
    fwrite(&data->num, sizeof(int), 1, fp);
    // 写入字符串长度(包含终止符,方便读取时分配内存)
    size_t name_len = strlen(data->name) + 1;
    fwrite(&name_len, sizeof(size_t), 1, fp);
    // 写入字符串内容
    fwrite(data->name, sizeof(char), name_len, fp);
    fclose(fp);
    return 0;
}
修正后的读取函数
int readData(char *filename) { // 注意你原来的参数写错了,是char不是chhar
    FILE *fp = fopen(filename, "rb");
    details data;
    // 读取num
    fread(&data.num, sizeof(int), 1, fp);
    // 读取字符串长度
    size_t name_len;
    fread(&name_len, sizeof(size_t), 1, fp);
    // 分配内存存储字符串
    data.name = malloc(name_len);
    // 读取字符串内容
    fread(data.name, sizeof(char), name_len, fp);
    
    // 这里可以使用读取到的数据
    printf("读取到的num: %d,name: %s\n", data.num, data.name);
    
    // 记得释放内存,避免泄漏
    free(data.name);
    fclose(fp);
    return 0;
}

最后还要提个小细节:你代码里的readData参数写成了chhar *,是拼写错误,要改成char *,否则编译都通不过。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:29:04