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

如何将包含指针成员的C语言结构体数据保存到二进制文件中

问题1:Breadboard结构体直接写入的问题

你当前直接fwrite整个Breadboard结构体,确实会把resistances这个二级指针的虚拟地址值写入文件,这个值是当前进程运行时的内存地址,下次读取文件时完全无效,确实不需要存储。
如果要跳过这个指针的存储,不要直接写入整个结构体,单独写入内部的三个普通成员即可:

// 替换原有写入整个Breadboard的fwrite代码
size_t h_written = fwrite(&bb_pointer->height, sizeof(int), 1, fp_board);
size_t w_written = fwrite(&bb_pointer->width, sizeof(int), 1, fp_board);
size_t cnt_written = fwrite(&bb_pointer->resistance_count, sizeof(int), 1, fp_board);
if (h_written != 1 || w_written !=1 || cnt_written !=1) {
    fclose(fp_board);
    return false;
}

如果你不想改现有逻辑,也可以继续写入整个结构体,读取时忽略resistances字段的内容即可,确实不会影响后续操作,只是浪费了几个字节的存储空间。

问题2:Resistance结构体写入的问题

你原来的写法确实是在写入指针数组的地址值,不是结构体本身的实际数据。你修改的加*的写法仅在特殊场景下有效:你的Resistance** resistances指向的指针数组里的所有Resistance*,都指向连续排列的Resistance结构体。但绝大多数场景下你是循环malloc每个Resistance结构体的,这时候这些结构体在内存中不连续,直接解引用写入resistance_count个数据只会成功写入第一个结构体,后续内容都是越界访问的垃圾数据。
通用的正确写法是循环逐个写入每个Resistance结构体:

for (int i=0; i<bb_pointer->resistance_count; i++) {
    size_t w = fwrite(bb_pointer->resistances[i], sizeof(Resistance), 1, fp_resistances);
    if (w != 1) {
        fclose(fp_resistances);
        return false;
    }
}

二进制读写的核心逻辑

记住一个核心原则:永远不要把指针值写入二进制文件,指针值是当前进程的临时内存地址,下次启动程序、换个进程读取文件时这个地址完全无效,你要写入的永远是指针指向的实际数据。
读取的时候逻辑和写入完全对应:

  1. 先读height、width、resistance_count三个值
  2. 根据resistance_count的数值,先申请Resistance**指针数组的内存,再逐个申请每个Resistance结构体的内存,循环读取每个结构体的数据填充即可。

如果需要验证二进制文件内容,可以使用Windows平台的WinHex、Linux/macOS平台的hexdump命令直接查看二进制内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 08:36:08