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

C++使用Boost序列化反序列化时的内存泄漏问题修复咨询

Boost序列化内存泄漏修复与正确用法

泄漏原因分析

  • 第一处明确泄漏:序列化阶段创建的A* a = new A();使用后未调用delete,导致堆内存未释放。
  • 关于friend class boost::serialization::access;的Valgrind提示:这是Boost序列化库内部的静态元数据对象,属于库层面的内存管理,并非业务代码导致的泄漏,属于无害误报,无需手动处理。
  • 你误解的“先创建空对象再反序列化生成两个对象”不成立:反序列化到已存在的对象时,仅覆盖该对象的成员变量值,不会额外创建新对象,这部分逻辑本身是正确的。

代码修复

修复内存泄漏

只需在序列化完成后,释放创建的堆对象:

// 序列化
A* a = new A();
(*a).num = 1;
serialization(a, "/../..");
delete a; // 新增:释放序列化用的对象

完整可编译修复代码

#include <boost/serialization/access.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <fstream>
#include <iostream>
#include <cstdint>
#include <string>

using namespace std;

class A
{
private:
    friend class boost::serialization::access; 

public:
    uint64_t num;

    template<class Archive> // 原代码缺失模板参数,必须补上才能编译
    void serialize(Archive& ar, const unsigned int version)
    {
        ar & num;
    }
};

void serialization(A* t, const string path)
{
    std::ofstream ofs(path, std::ios::binary);
    boost::archive::binary_oarchive oa(ofs);
    oa << *t;
    ofs.close();
}

void deserialization(A* t, const string path)
{
    std::ifstream ifs(path, std::ios::binary);
    boost::archive::binary_iarchive ia(ifs);
    ia >> *t;
    ifs.close();
}

int main()
{
    // 序列化
    A* a = new A();
    (*a).num = 1;
    serialization(a, "./test.bin"); // 建议使用有效路径,避免/../..这类无效路径
    delete a; // 释放序列化对象

    // 反序列化
    A* a2 = new A();  
    deserialization(a2, "./test.bin");
    cout << (*a2).num << endl;
    delete(a2);

    return 0;
}

正确的反序列化到堆内存的方式

有两种常见用法:

  • 预先分配对象(当前用法):手动new对象,将指针传入反序列化函数,Boost直接把数据写入该对象的内存空间,使用完成后手动delete即可,适合需要手动控制对象生命周期的场景。
  • Boost自动分配对象:若希望直接从归档生成堆对象,可以直接序列化/反序列化指针,Boost会自动完成对象分配,示例:
    void serialization(A* t, const string path)
    {
        std::ofstream ofs(path, std::ios::binary);
        boost::archive::binary_oarchive oa(ofs);
        oa << t; // 直接序列化指针
        ofs.close();
    }
    
    A* deserialization(const string path)
    {
        A* t = nullptr;
        std::ifstream ifs(path, std::ios::binary);
        boost::archive::binary_iarchive ia(ifs);
        ia >> t; // Boost自动new对象并赋值给t
        ifs.close();
        return t;
    }
    
    使用这种方式时,记得在使用完返回的指针后调用delete释放内存。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 22:48:20