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

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的逻辑,只需要修改两处即可:

  1. 构造输出流时补充读权限:std::ostringstream out(std::ios::binary | std::ios::in);
  2. 反序列化时直接用输出流的字符串构造输入流:std::istringstream is(os.str(), std::ios::binary);,删掉替换rdbuf的逻辑。

修复后运行输出为:

loaded.number_: 4

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 03:06:02