You need to enable JavaScript to run this app. C++含string结构体的二进制读写(适配单链表,解决读取报错)
优惠活动
大模型
产品
解决方案
定价
更多

C++含string结构体的二进制读写(适配单链表,解决读取报错)

问题根因定位

你当前遇到的报错根源并非仅Read函数内的resize逻辑错误,首先是Save函数的序列化设计本身存在根本性缺陷:

  • std::string 不属于POD(平凡可复制)类型,结构体中的string成员本身不存储连续的字符串字符内容,仅保存指向堆内存中字符串内容的指针、当前字符串长度、堆块容量三类运行时元信息。
  • 你在Save函数中直接把整个Data结构体的内存数据写入文件的操作,实际落盘的是这些临时的内存地址、容量数值,而非字符串本身的字符内容——哪怕你提前记录了字符串长度,这些堆地址值在程序重启后属于完全无效的悬空地址,根本无法还原原始字符串。
  • Read函数中对string做resize的逻辑本身方向正确,但由于Save端写入的不是有效字符串内容,必然会出现读取偏移错位、内存越界访问的运行报错。

修复实现方案

二进制读写逻辑必须严格对称,绝对不能对包含string的结构体做整块内存的二进制序列化,修正后的读写逻辑如下:

  1. 修正Save端写入逻辑(删除直接整块写结构体内存的错误操作,和你已有的长度记录逻辑对齐):
    遍历单链表节点时,按照固定顺序依次写入:
    • name成员的字符串长度
    • surname成员的字符串长度
    • grade成员的int值
    • name对应的实际字符序列
    • surname对应的实际字符序列
      核心实现代码参考:
    // 单链表节点遍历内的写入逻辑
    size_t nameLen = curr->data.name.size();
    size_t surLen = curr->data.surname.size();
    note.write(reinterpret_cast<const char*>(&nameLen), sizeof(nameLen));
    note.write(reinterpret_cast<const char*>(&surLen), sizeof(surLen));
    note.write(reinterpret_cast<const char*>(&curr->data.grade), sizeof(curr->data.grade));
    note.write(curr->data.name.c_str(), nameLen);
    note.write(curr->data.surname.c_str(), surLen);
    
  2. 修正Read端读取逻辑(调整resize的执行时机,和Save的写入顺序严格对齐):
    按照Save端的固定顺序依次读取字段,读完长度后先给对应string成员分配目标长度的内存空间,再把文件中读到的字符流写入string的内部缓冲区,不要先整块读入结构体内存再单独resize。
    核心实现代码参考:
    // 读取文件构造新链表节点的逻辑
    size_t nameLen, surLen;
    int grade;
    rfrom.read(reinterpret_cast<char*>(&nameLen), sizeof(nameLen));
    rfrom.read(reinterpret_cast<char*>(&surLen), sizeof(surLen));
    rfrom.read(reinterpret_cast<char*>(&grade), sizeof(grade));
    
    Data nodeData;
    nodeData.grade = grade;
    // 先完成内存分配
    nodeData.name.resize(nameLen);
    nodeData.surname.resize(surLen);
    // 再将读到的字符直接写入已分配的缓冲区
    rfrom.read(nodeData.name.data(), nameLen);
    rfrom.read(nodeData.surname.data(), surLen);
    

避坑提示

  • 禁止对包含std::string、裸指针、自定义非POD成员的结构体做整块内存的二进制落盘,这类操作写入的是进程运行时的临时内存地址,跨程序运行周期完全不可复用
  • 读写全流程的字段顺序、字段类型、字段占用字节长度必须严格一致,一旦出现任意一步的顺序错位,后续所有读取的文件偏移量都会完全错乱,直接触发内存访问异常
  • 每完成一次读写操作,需要检查文件流的状态位,确认没有提前触达EOF、读写长度不足的异常,避免残缺数据导致的未定义行为

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.23 03:36:06