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

C++读写含vector成员的结构体向量到二进制文件报错如何解决

问题根因

你遇到的报错本质是不能直接对包含非POD(普通旧数据)类型的结构体做二进制裸读写:

  • std::vector属于非POD类型,内部存储的是指向堆内存的指针、容量、大小等控制信息,你直接file.write写info结构体的时候,只是把这些指针、控制信息的当前内存值写入了文件,并没有写入vector实际存储的MyStruct元素内容
  • 读取的时候你直接把二进制内容覆盖到新的info实例的内存空间,会破坏vector的内部结构,后续vector析构、访问的时候就会触发访问越界错误,也就是你遇到的0xC0000005报错。
修复方案

你需要手动实现结构体的序列化/反序列化逻辑,逐个成员处理读写,特殊处理vector类型:

修改后的完整代码

#include <iostream>
#include <fstream>
#include <vector>
#include <cstring>

struct MyStruct
{
    int a;
};

struct info
{
    char name[30];
    int age;
    char bbl[20];
    std::vector<MyStruct> my;
};

// 序列化单个info对象到文件
void write_info(std::ofstream& file, const info& inf)
{
    // 写入固定长度的基础成员
    file.write(inf.name, sizeof(inf.name));
    file.write(reinterpret_cast<const char*>(&inf.age), sizeof(inf.age));
    file.write(inf.bbl, sizeof(inf.bbl));
    // 先写入vector的元素个数
    size_t my_size = inf.my.size();
    file.write(reinterpret_cast<const char*>(&my_size), sizeof(my_size));
    // 再逐个写入vector里的每个MyStruct元素
    for (const auto& item : inf.my)
    {
        file.write(reinterpret_cast<const char*>(&item.a), sizeof(item.a));
    }
}

// 从文件反序列化单个info对象
bool read_info(std::ifstream& file, info& inf)
{
    // 读取固定长度的基础成员
    if (!file.read(inf.name, sizeof(inf.name))) return false;
    if (!file.read(reinterpret_cast<char*>(&inf.age), sizeof(inf.age))) return false;
    if (!file.read(inf.bbl, sizeof(inf.bbl))) return false;
    // 先读取vector的元素个数
    size_t my_size = 0;
    if (!file.read(reinterpret_cast<char*>(&my_size), sizeof(my_size))) return false;
    // 清空原vector,预留空间后逐个读取元素
    inf.my.clear();
    inf.my.reserve(my_size);
    for (size_t i = 0; i < my_size; ++i)
    {
        MyStruct item;
        if (!file.read(reinterpret_cast<char*>(&item.a), sizeof(item.a))) return false;
        inf.my.push_back(item);
    }
    return true;
}

void create(const std::vector<info>& test)
{
    // 这里用trunc覆盖旧文件,避免追加导致格式错乱,如果你确实需要追加写入可以改回ios::app
    std::ofstream file("info.dat", std::ios::binary | std::ios::trunc);
    for (const auto& inf : test)
    {
        write_info(file, inf);
    }
}

int main()
{
    info info1;
    std::vector<info> test;
    info1.age = 3443;
    std::cin >> info1.name;
    std::cin >> info1.bbl;
    MyStruct my;
    my.a = 4;
    info1.my.push_back(my);
    test.push_back(info1);
    
    std::cout << '\n';
    create(test);
    
    test.clear();

    {
        std::ifstream file("info.dat", std::ios::binary);
        info inf;
        while (read_info(file, inf))
        {
            test.push_back(inf);
        }
    }

    for (size_t i = 0; i < test.size(); i++)
    {
        std::cout << "{ " << test[i].name << ", " << test[i].age << ", " << test[i].bbl << ", my数组长度: " << test[i].my.size() << ", my[0].a值: " << test[i].my[0].a << " } ";
    }
    std::cout << '\n';
    return 0;
}

额外注意事项

  • 这种二进制序列化的文件不具备跨平台、跨编译器版本兼容性,不同环境下的结构体对齐规则、int/long等基础类型的长度可能不一样,如果需要兼容需要显式指定固定长度类型(比如int32_t替代int)、关闭结构体对齐。
  • 如果后续结构体成员更复杂,建议用专门的序列化库比如protobuf、flatbuffers来处理,避免手动写序列化逻辑出错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 19:24:06