c++不规则数组无原生序列化支持,需依格式选方案:json用nlohmann/json自动处理嵌套vector,二进制需手写含长度前缀的序列化,protobuf需flatten为repeated字段并配lengths。

不规则数组在C++里没有原生表示,得先明确数据结构
所谓“不规则数组”,比如 vector<vector>></vector>、vector<array>></array> 或嵌套深度不一的 vector<variant>></variant>,C++标准库不提供统一序列化接口。你不能直接对 std::vector 或 std::array 调用某个通用函数就完成序列化——它取决于你用什么格式(JSON、binary、Protocol Buffers)、是否跨平台、是否需版本兼容。
常见错误是试图把指针或未初始化的 vector 成员直接 memcpy,结果读出来全是零或乱码;或者用 reinterpret_cast<char></char> 强转整个对象,忽略虚表、padding 和 STL 内部指针布局。
- 如果只是临时进程内传递,优先用
std::vector<:byte></:byte>手动展平 + 索引偏移 - 若需跨语言或持久化,选
json(如 nlohmann/json)或protobuf(需先定义.proto描述嵌套结构) - 避免用
std::string存二进制数据——它不保证 '\0' 安全,且c_str()可能截断
用 nlohmann/json 序列化 vector> 最简路径
nlohmann/json 对嵌套容器支持好,且自动处理大小不一的子数组(比如 {{1}, {2,3}, {4,5,6}})。但它要求元素类型可序列化:基础类型、STL 容器、自定义类需提供 to_json/from_json。
示例:序列化 vector<vector>></vector>
#include <nlohmann>
using json = nlohmann::json;
vector<vector>> irregular = {{1.1}, {2.2, 3.3}, {4.4, 5.5, 6.6}};
json j = irregular; // 自动推导,生成 JSON 数组的数组
string s = j.dump(); // → "[[1.1],[2.2,3.3],[4.4,5.5,6.6]]"
</vector></nlohmann>
- 反序列化时,
json::parse(s).get<vector>>>()</vector>可直接还原,但会抛json::type_error如果 JSON 结构不匹配 - 不要依赖
dump(2)带缩进——它增加体积且无语义,传输时用dump()无空格版本 - 若含自定义类(如
struct Point { double x,y; };),必须显式定义void to_json(json&, const Point&)
二进制序列化要注意内存布局和字节序
想最小体积、最高性能?手写二进制序列化。但 vector 的 data() 指针只指向当前元素块,不包含 size 信息;子数组长度各异,必须显式存长度前缀。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
典型安全做法:
- 先写外层数组长度
N(如uint32_t) - 对每个子数组,先写其长度
M_i,再写M_i个元素(按sizeof(T)连续拷贝) - 所有整数用网络字节序(
htons/htonl),避免小端/大端混用 - 浮点数不转换字节序,但要确认收发双方 IEEE 754 兼容(x86 和 ARM 通常没问题)
错误示范:memcpy(buf, &v, sizeof(v)) —— v 是 vector 对象本身,只拷了内部指针和 size,不是数据。
Protobuf 处理不规则嵌套需要 flatten 或 repeated 字段
Protocol Buffers 不支持“数组的数组”语法,但可用 repeated 字段模拟。例如把 vector<vector>></vector> 映射为:
message IrregularInts {
repeated int32 values = 1;
repeated uint32 lengths = 2; // 每个子数组长度
}
序列化时,把所有子数组 concat 到 values,同时记录每个子数组长度到 lengths。反序列化时靠 lengths 切分 values。
- 优势:紧凑、高效、天然支持多语言
- 坑点:
lengths必须与values严格对应,否则解析崩溃;建议加校验字段(如uint32 total_count = 3;) - 别用
oneof或嵌套message来模拟不规则结构——它会让 schema 膨胀且难以维护
真正麻烦的是运行时才知道嵌套层数(比如树形结构),这时要么预定义最大深度,要么改用 JSON 或自定义二进制协议。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










