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

受限无向图场景下智能指针的正确使用方案咨询

C++智能指针重构方案:节点连接模型

核心思路

明确所有权关系是解决内存泄漏的关键:

  • 顶层容器持有所有节点的所有权,用std::shared_ptr管理
  • 节点内部的交叉引用(包括自引用)用std::weak_ptr,避免循环引用导致的内存泄漏
  • 禁止裸指针直接持有对象,所有指针访问需通过智能指针的安全检查

重构后的代码实现

#include <memory>
#include <vector>

// 基类继承enable_shared_from_this,允许节点获取自身的智能指针
struct Node : std::enable_shared_from_this<Node> {};

struct Conn {
    // 用weak_ptr存储owner,避免自引用导致的循环引用
    std::weak_ptr<Node> owner;
    // targets存储sink节点的弱引用,不持有所有权
    std::vector<std::weak_ptr<Node>> targets;
    // 其他字段
};

struct NodeA : public Node {
    Conn conn;

    NodeA() {
        // 初始化owner为自身的弱引用
        conn.owner = shared_from_this();
    }

    // 安全添加目标节点的方法
    void add_target(std::weak_ptr<Node> target) {
        conn.targets.push_back(std::move(target));
    }

    // 其他字段
};

struct NodeB : public Node {
    // 存储源节点的弱引用,替代原有的Conn&,避免悬空引用
    std::weak_ptr<NodeA> source_node;

    // 构造函数传入源节点的智能指针
    NodeB(std::weak_ptr<NodeA> src) : source_node(std::move(src)) {}

    // 安全获取Conn的方法,检查源节点是否存活
    Conn* get_conn() {
        if (auto src = source_node.lock()) {
            return &src->conn;
        }
        return nullptr; // 源节点已销毁,返回空指针
    }

    // 其他字段
};

// 顶层容器:持有所有节点的所有权
std::vector<std::shared_ptr<Node>> sink_nodes; // 存储sink节点(NodeB)
std::vector<std::shared_ptr<NodeA>> source_nodes; // 存储源节点(NodeA)

使用示例

// 创建源节点,由source_nodes持有所有权
auto source = std::make_shared<NodeA>();
source_nodes.push_back(source);

// 创建sink节点,关联到源节点,由sink_nodes持有所有权
auto sink = std::make_shared<NodeB>(source);
sink_nodes.push_back(sink);

// 将sink节点添加到源节点的target列表
source->add_target(sink);

// 访问NodeB的Conn时,先检查源节点是否存活
if (auto conn = sink->get_conn()) {
    // 安全操作conn
}

关键细节说明

  • 所有权隔离:顶层容器是唯一持有节点所有权的地方,shared_ptr确保节点在不再被需要时自动销毁
  • 避免循环引用:所有内部引用(包括Conn的owner、targets,NodeB的源节点引用)都用weak_ptr,不会增加引用计数,彻底解决循环引用导致的内存泄漏
  • 安全访问:使用weak_ptr::lock()获取shared_ptr来访问对象,自动检查对象是否存活,避免悬空指针问题
  • 替代裸引用:原NodeB中的Conn&替换为weak_ptr<NodeA>,避免源节点销毁后引用失效的风险

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 19:13:44