C++类状态与二进制流序列化/反序列化输出0问题排查咨询
问题原因与修复方案
核心问题点
- 构造
std::ostringstream时未开启读权限:你初始化输出流时只传了std::ios::binary,std::ostringstream默认自带std::ios::out权限,没有std::ios::in的情况下,内部缓冲区不支持读操作,后续尝试读取数据必然失败。 - 反序列化构造输入流的逻辑错误:你采用替换
rdbuf的方式关联输出流和输入流,一方面会导致输入流原本的空缓冲区泄漏,另一方面也受限于上面的读权限问题拿不到有效数据。 - 缺少IO操作结果校验:调用
read后没有判断操作是否成功,你拿到的0本质是未初始化的栈内存值,只是当前运行环境下栈内存刚好为0,属于未定义行为。
修复方案
更简单稳妥的实现是直接序列化返回二进制字符串,不需要传递整个流对象,修改后的代码如下:
class ForSerializationAsBinary { public: ForSerializationAsBinary() = default; explicit ForSerializationAsBinary(int number) : number_(number) {} // 直接返回序列化后的二进制字符串 std::string toBinary() { std::ostringstream out(std::ios::binary); out.write(reinterpret_cast<char*>(&number_), sizeof(int)); return out.str(); } static void fromBinary(ForSerializationAsBinary &obj, const std::string& binary) { std::istringstream is(binary, std::ios::binary); int n; // 校验read操作是否成功 if (is.read(reinterpret_cast<char*>(&n), sizeof(int))) { obj.number_ = n; } else { // 可根据需求加错误处理逻辑 obj.number_ = -1; } } int number_; }; TEST(Serialisation, SimpleSerialization) { ForSerializationAsBinary serializationAsBinary(4); auto binary = serializationAsBinary.toBinary(); ForSerializationAsBinary loaded; ForSerializationAsBinary::fromBinary(loaded, binary); std::cout << "loaded.number_: " << loaded.number_ << std::endl; }
如果你一定要保留返回std::ostringstream的逻辑,只需要修改两处即可:
- 构造输出流时补充读权限:
std::ostringstream out(std::ios::binary | std::ios::in); - 反序列化时直接用输出流的字符串构造输入流:
std::istringstream is(os.str(), std::ios::binary);,删掉替换rdbuf的逻辑。
修复后运行输出为:
loaded.number_: 4
内容的提问来源于stack exchange,提问作者CiaranWelsh
相关产品推荐
相关产品推荐

