直接write()含std::vector的结构体会出错,因只写入24字节对象头而非堆数据,导致读取时野指针崩溃;正确做法是先写size再写data,且元素类型须为POD。

结构体含 std::vector 时直接 write() 会出错
二进制写入结构体前没做序列化,write() 只拷贝了 std::vector 对象本身的 24 字节(指针+size+capacity),不是它指向的堆内存数据。读取时得到野指针,程序崩溃或读出乱码。
常见错误现象:read() 后 vec.size() 是个极大随机值,访问 vec[0] 段错误;或文件里只存了 24 字节,但你以为存了全部元素。
- 必须显式序列化
std::vector的size()和所有元素 - 元素类型要是 POD(如
int、double、自定义 POD 结构体),否则需递归处理 - 不要用
memcpy(&s, sizeof(s)),对含 STL 成员的结构体无效
std::vector 序列化到文件的最小安全写法
核心是先写长度,再写数据块。读取时反向操作:先读 size,再按 size 分配并读数据。
示例结构体:
立即学习“C++免费学习笔记(深入)”;
struct Record {
int id;
std::vector<double> values;
};写入逻辑:
- 用
ofstream::write()写id(sizeof(int)) - 写
values.size()(sizeof(size_t),注意跨平台可用uint64_t替代) - 若
values非空,再写values.data()块(values.size() * sizeof(double))
关键点:写入前确保 values 数据连续(std::vector 保证这点),且不依赖对象内部布局。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
含嵌套 std::vector 或自定义结构体怎么办
只要嵌套成员是 POD,就逐层展开序列化。遇到非 POD(比如含 std::string、虚函数、引用),必须手动定义序列化协议。
例如结构体含 std::vector<Record>:
- 先写外层
vec.size() - 对每个
Record r,依次写r.id、r.values.size()、r.values.data() - 读取时严格按同样顺序和大小解析,不能跳过任何字段
性能影响:深度嵌套会增加 I/O 次数和内存拷贝,但比通用序列化库(如 protobuf)轻量;兼容性上,size_t 大小在 32/64 位系统不同,建议统一用 uint32_t 存长度。
为什么不用 boost::serialization 或 protobuf
它们能自动处理复杂类型,但引入依赖、编译变慢、二进制格式不透明。实战中如果只是临时存几个 std::vector<float> 给自己用,手写序列化更可控。
容易踩的坑:
-
boost::archive::binary_oarchive默认不保证跨平台字节序,需额外配置 -
protobuf要写 .proto 文件、生成代码,小项目显得重 - 手写时忘了写
static_assert(std::is_pod_v<T>),对非 POD 类型静默失败
真正麻烦的从来不是怎么写进去,而是读的时候——长度字段读错一个字节,后面全乱。务必校验每一步的 gcount() 或 failbit。

















