不能直接对std::vector对象调用write(),因其含指针等非数据成员;应先写大小再写data()指向的POD元素;非POD类型需自定义序列化;读取须严格按序且校验。

直接 write 整个 vector 内存会出错
不能对 std::vector 对象本身调用 write(),哪怕它底层是连续内存。因为 vector 对象包含指针(data_)、大小(size_)和容量(capacity_)等成员,直接二进制写入会把指针值(如 0x7fffabcd1234)也存进去,读取时这个地址早已失效,且跨平台/跨编译器不兼容。
只序列化 data() 指向的元素数据
真正要保存的是元素内容,不是容器结构。需分两步:先写长度,再写元素数据。适用于 vector 元素是 POD 类型(如 int、float、double、struct 无虚函数/非POD成员)的情况。
std::ofstream ofs("data.bin", std::ios::binary);
size_t n = vec.size();
ofs.write(reinterpret_cast(&n), sizeof(n));
if (!vec.empty()) {
ofs.write(reinterpret_cast(vec.data()), vec.size() * sizeof(vec[0]));
} 读取时必须严格按写入顺序反向操作
顺序错乱或类型不匹配会导致未定义行为,比如把 size_t 当 int 读,或跳过长度直接读数据,都会让后续全部错位。
- 先读
size_t n,检查是否为合法值(比如n > SIZE_MAX / sizeof(T)就该拒绝) - 然后
vec.resize(n),再read()到vec.data() - 务必检查
gcount()或rdstate(),文件损坏或截断时不能假装成功
非 POD 类型(如 std::string、含指针的 struct)不能直接二进制 dump
std::string 在不同 STL 实现中内存布局不同(SSO 是否启用、内部字段顺序),vector<:string> 直接写 data() 只会保存短字符串的栈内副本或野指针,毫无可移植性。
立即学习“C++免费学习笔记(深入)”;
此时必须自定义序列化逻辑:
- 对每个
std::string,先写其size()(uint32_t),再写字符数据 - 对含
std::vector成员的struct,递归处理每个字段 - 考虑用
std::span(C++20)或char*显式表达字节序列,避免类型误读
二进制存储看似简单,但一旦涉及长度、对齐、端序、生命周期,细节就藏在读写的每一行 reinterpret_cast 后面。别信“只要内存连续就能直接写”这种直觉。










