【内存泄漏元凶曝光】:shared_ptr循环引用的4种检测与修复方法

shared_ptr循环引用问题以及解决方法 shared_ptr循环引用问题以及解决方法一、shared_ptr循环引用问题例子一例子二例子三二、weak_ptr解决循环引用问题 一、shared_ptr循环引用问题 什么是循环引用,两个对象相互使用shared_ptr指向对方。造成的后果是:内存泄漏 例子一 下面是循环引用的例子 #include <iostream> #include <memory> using namespace std; class A; class B; class A { public: 阅读详情

第一章:shared_ptr循环引用问题的由来

在C++的智能指针体系中,std::shared_ptr通过引用计数机制自动管理动态对象的生命周期。每当一个新的shared_ptr指向同一对象时,引用计数加一;当shared_ptr被销毁或重新赋值时,引用计数减一;当计数为零时,对象自动被释放。这一机制有效避免了内存泄漏,但在某些场景下也可能引发资源无法释放的问题——即循环引用。

循环引用的产生条件

当两个或多个对象通过shared_ptr相互持有对方的强引用时,引用计数将永远不会归零,即使这些对象已不再被外部使用。典型场景出现在双向链表、父子节点结构或观察者模式中。 例如,以下代码展示了两个对象互相持有shared_ptr导致的循环引用:

#include <memory>
struct Node {
    std::shared_ptr<Node> parent;
    std::shared_ptr<Node> child;

    ~Node() {
        std::cout << "Node destroyed\n";
    }
};

int main() {
    auto a = std::make_shared<Node>();
    auto b = std::make_shared<Node>();
    a->child = b;
    b->parent = a; // 形成循环引用
    return 0; // 此处a和b的引用计数均为1,析构函数不会被调用
}
上述代码中,对象a和b的引用计数始终不为零,导致内存泄漏。

常见解决方案对比

为打破循环,通常采用std::weak_ptr替代其中一个方向的shared_ptr,以避免增加引用计数。
方案优点缺点
使用 weak_ptr打破循环,安全访问需显式检查是否有效
手动重置 shared_ptr控制时机明确易出错,维护成本高
通过合理设计对象间的引用关系,可从根本上避免循环引用问题。

第二章:循环引用的形成机制与典型场景

2.1 shared_ptr引用计数原理与内存管理模型

`std::shared_ptr` 是 C++ 中实现自动内存管理的核心智能指针之一,其核心机制基于**引用计数**。每当一个新的 `shared_ptr` 实例共享同一块动态内存时,引用计数加一;当某个实例析构时,计数减一;仅当计数降为零时,资源被自动释放。
引用计数的存储结构
`shared_ptr` 内部维护两个指针:一个指向实际数据(managed object),另一个指向控制块(control block),其中包含引用计数、弱引用计数和删除器等元信息。
std::shared_ptr<int> p1 = std::make_shared<int>(42);
std::shared_ptr<int> p2 = p1; // 引用计数从1变为2
上述代码中,`p1` 和 `p2` 共享同一对象,控制块中的引用计数为2。当 `p1` 和 `p2` 均离开作用域后,对象才被销毁。
线程安全特性
引用计数的增减操作是原子的,保证多线程下引用计数的安全更新,但不保证所指向对象的线程安全。

2.2 双向链表中父子节点的循环引用实例分析

在双向链表中,每个节点包含前驱和后继指针,容易引发父子节点间的循环引用问题。这种结构虽提升了遍历灵活性,但也增加了内存管理复杂度。
循环引用示例

type Node struct {
    Value    int
    Prev     *Node
    Next     *Node
}

// 构建两个互相引用的节点
nodeA := &Node{Value: 1}
nodeB := &Node{Value: 2}
nodeA.Next = nodeB
nodeB.Prev = nodeA // 形成双向连接
上述代码中,nodeA 指向 nodeB,而 nodeB 又通过 Prev 指回 nodeA,构成循环引用。在垃圾回收机制下,若无显式断开,该引用链将无法释放。
内存影响分析
  • 对象生命周期延长,导致内存滞留
  • 频繁增删操作加剧内存碎片化
  • GC 压力上升,影响系统整体性能

2.3 观察者模式中监听器注册导致的循环依赖

在观察者模式中,主体(Subject)维护一组监听器(Observer),当状态变化时通知所有监听器。然而,若监听器在回调中反向引用并持有主体实例,容易引发循环依赖。
典型场景分析
例如,UI组件作为观察者注册到数据模型,而数据模型又间接引用该UI组件,形成双向强引用。在垃圾回收机制下,此类结构可能导致内存泄漏。
  • 主体对象无法被释放,因监听器仍持有其引用
  • 监听器也无法释放,因主体持有其回调函数
解决方案示例
使用弱引用或显式解注册机制可打破循环。以下为Go语言中的弱引用实现片段:

type Subject struct {
    observers []*weak.Observer
}

func (s *Subject) Notify() {
    for _, obs := range s.observers {
        if obj := obs.Get(); obj != nil {
            obj.(Observer).Update()
        }
    }
}
上述代码通过弱引用包装观察者实例,避免主体对观察者的强引用,从而切断循环依赖链。

2.4 树形结构中父节点与子节点的强引用陷阱

在树形数据结构中,父节点持有子节点的引用通常被认为是自然的设计方式。然而,当子节点也强引用其父节点时,容易形成双向强引用,导致内存泄漏,尤其在垃圾回收机制依赖引用计数的语言中更为明显。
常见语言中的表现
例如,在 Go 或 Python 中,若节点定义如下:
type Node struct {
    Value    string
    Children []*Node
    Parent   *Node // 反向引用
}
当父子节点相互持有指针,且无外部引用释放路径时,即使逻辑上应被销毁的子树仍会因引用环而驻留内存。
解决方案对比
  • 使用弱引用(如 Python 的 weakref)打破循环
  • 显式调用清理方法,手动置 Parent = nil
  • 设计单向引用结构,延迟遍历时重建路径
方案优点缺点
弱引用自动管理语言支持有限
手动清理控制精确易遗漏

2.5 Lambda表达式捕获this引发的隐式循环引用

在C++和Java等语言中,Lambda表达式常用于简化回调逻辑。然而,当Lambda捕获`this`指针时,可能无意中引入隐式循环引用。
问题成因
当对象持有Lambda作为成员,并在Lambda体内通过`this`访问成员变量时,若捕获方式为值捕获(如C++中的`[=]`),会复制`this`指针。若该Lambda被长期持有(如异步任务队列),而对象未正确释放,则导致内存泄漏。

class DataProcessor {
    std::function task;
public:
    void setup() {
        task = [this]() { process(); }; // 捕获this,形成强引用
    }
    void process() { /* 处理逻辑 */ }
};
上述代码中,`DataProcessor`实例将自身捕获进`task`,若`task`未被清除,析构函数无法触发,造成资源泄露。
解决方案
  • 使用弱引用捕获:C++中可结合`std::weak_ptr`;Java中使用`WeakReference<ThisType>`
  • 显式清理Lambda:在析构前置空持有的可调用对象

第三章:检测循环引用的专业工具与方法

3.1 使用静态分析工具识别潜在的引用环路

在 Go 语言开发中,引用环路可能导致内存泄漏或意外的行为。静态分析工具能够在编译期帮助开发者发现这类问题。
常用静态分析工具
  • go vet:官方提供的静态检查工具,可检测常见错误;
  • staticcheck:功能更强大的第三方工具,支持深度代码分析。
示例:使用 staticcheck 检测结构体循环引用

type User struct {
    Name   string
    Group  *Group  // 引用 Group
}

type Group struct {
    Admin *User    // 形成环路:User → Group → User
}
上述代码中,User 和 Group 互相持有对方的指针,构成引用环路。通过执行 staticcheck ./...,工具会提示存在潜在的循环依赖问题,有助于提前重构设计。

3.2 借助Valgrind与AddressSanitizer定位内存泄漏

在C/C++开发中,内存泄漏是常见且难以察觉的错误。借助Valgrind和AddressSanitizer可高效定位问题根源。
使用Valgrind检测内存泄漏
Valgrind是一款强大的内存调试工具,能监控程序运行时的内存使用情况。编译程序后执行:
valgrind --leak-check=full ./your_program
输出将详细列出未释放的内存块、分配位置及泄漏类型,适用于Linux环境下的深度分析。
集成AddressSanitizer快速诊断
AddressSanitizer(ASan)是编译器内置的内存错误检测器,性能开销小。通过以下编译选项启用:
gcc -fsanitize=address -g -o program program.c
运行程序时,ASan会实时报告内存泄漏点,精确到源码行号,适合CI/CD集成。
  • Valgrind:功能全面,无需重新编译,但运行较慢;
  • AddressSanitizer:速度快,需重新编译,支持堆栈展开。

3.3 自定义引用计数监控与日志追踪技术

在高并发系统中,对象生命周期管理至关重要。通过自定义引用计数机制,可精准掌握资源的使用状态,避免内存泄漏或过早释放。
引用计数核心结构设计
type RefCounted struct {
    data      interface{}
    refCount  int64
    mu        sync.Mutex
    logger    *log.Logger
}
该结构封装数据、引用计数、互斥锁和日志记录器。每次增加引用时调用 IncRef(),减少时调用 DecRef(),并在计数归零时触发资源回收。
日志追踪与调试支持
  • 每次引用变更记录操作线程ID和调用栈
  • 集成 leveled-logging,区分 INFO、WARN 级别事件
  • 支持动态开启/关闭详细追踪模式
结合计数变化日志,可构建完整的资源生命周期轨迹,辅助定位复杂场景下的资源竞争问题。

第四章:打破循环引用的四种实战修复策略

4.1 使用weak_ptr解除单边强引用实现解耦

在C++的智能指针体系中,std::shared_ptr通过引用计数管理对象生命周期,但双向强引用易导致内存泄漏。此时,std::weak_ptr作为弱引用指针,可打破循环依赖。
weak_ptr的基本机制
weak_ptr不增加引用计数,仅观察shared_ptr所管理的对象。需通过lock()获取临时shared_ptr以安全访问对象。

#include <memory>
#include <iostream>

struct Node {
    std::shared_ptr<Node> parent;
    std::weak_ptr<Node> child;  // 避免循环引用

    ~Node() { std::cout << "Node destroyed\n"; }
};
上述代码中,父节点通过shared_ptr持有子节点,子节点使用weak_ptr回引父节点,有效解耦。
典型应用场景
  • 观察者模式中的监听器管理
  • 缓存系统中避免对象被意外释放
  • 树形结构中父子节点的反向引用

4.2 接口设计优化:引入生命周期管理契约

在微服务架构中,接口的稳定性与资源的可控性高度依赖于明确的生命周期管理。通过定义统一的生命周期契约,可有效协调服务间资源的创建、使用与释放。
生命周期契约接口定义
type Lifecycle interface {
    Init() error        // 初始化资源,如数据库连接
    Start() error       // 启动服务逻辑
    Stop() error        // 优雅关闭,释放资源
}
该接口规范了组件的标准生命周期行为。Init 负责预加载配置与依赖;Start 触发业务监听;Stop 确保正在进行的请求处理完成后再关闭。
实现优势
  • 提升系统可靠性:避免资源泄露
  • 增强可测试性:便于模拟状态切换
  • 统一运维入口:支持标准化健康检查与热更新

4.3 RAII扩展技巧:结合作用域锁打破循环

在复杂资源管理中,RAII 可与作用域锁结合,有效避免因资源持有周期过长导致的死锁或循环依赖。
作用域锁的RAII实现
通过局部作用域自动释放锁,确保异常安全与资源及时归还:

std::mutex mtx;
{
    std::lock_guard lock(mtx); // 构造时加锁
    // 临界区操作
} // 析构时自动解锁,打破潜在循环等待
该机制利用栈对象生命周期绑定锁状态,防止跨作用域误持锁。
打破循环依赖的典型场景
  • 多线程访问共享资源时,按固定顺序获取锁仍可能因延迟释放引发死锁
  • 使用RAII锁简化嵌套调用中的解锁逻辑,缩短持锁时间窗口

4.4 智能指针使用规范与代码审查清单

智能指针选择准则
在C++中,应优先使用`std::unique_ptr`表示独占所有权,`std::shared_ptr`用于共享所有权,避免裸指针管理资源。
  • std::unique_ptr:适用于单一所有者场景,性能开销最小
  • std::shared_ptr:引用计数机制,注意循环引用风险
  • std::weak_ptr:配合shared_ptr打破循环引用
典型代码示例与分析

std::shared_ptr<Resource> ptr1 = std::make_shared<Resource>(42);
std::weak_ptr<Resource> weakRef = ptr1;
if (auto ptr2 = weakRef.lock()) {
    ptr2->use();
} // 安全访问,避免悬空指针
上述代码通过weak_ptr::lock()获取临时shared_ptr,确保对象生命周期有效,防止竞态条件。
代码审查检查表
检查项推荐做法
资源分配使用make_shared或make_unique
所有权转移用std::move显式传递
循环引用第三方引用使用weak_ptr

第五章:总结与现代C++中的最佳实践建议

优先使用智能指针管理资源
手动内存管理易引发泄漏和悬垂指针。应广泛采用 std::unique_ptr 和 std::shared_ptr,结合 RAII 原则确保资源安全释放。
// 推荐:使用 unique_ptr 避免内存泄漏
std::unique_ptr<MyClass> obj = std::make_unique<MyClass>();
obj->doSomething();
// 离开作用域时自动析构
利用 auto 与范围 for 提升代码可读性
显式写出类型常冗余且易出错。合理使用 auto 可简化复杂迭代器声明,并增强泛型能力。
  1. 在迭代容器时优先使用范围 for 循环
  2. 配合 auto&& 处理通用引用场景
  3. 避免过度使用 auto 导致语义模糊
启用编译期检查以提升安全性
现代 C++ 支持 constexpr 函数与变量,可在编译阶段执行计算并验证逻辑。
特性推荐用法示例场景
constexpr定义编译期常量函数数学常量、配置参数
[[nodiscard]]标记不应忽略的返回值错误码、状态对象
避免原始循环,改用算法组合
标准库算法如 std::transform、std::find_if 更具表达力且易于优化。
[容器] --> 算法 + 谓词 --> [结果] 例如:vector -> std::remove_if + lambda -> 擦除无效元素
掌握智能指针shared_ptr的精髓:底层原理与实际应用全解析 C++智能指针shared_ptr是一种可以自动管理内存的智能指针,它是C++11新增的特性之一。与传统指针不同,shared_ptr可以自动释放所管理的动态分配对象的内存,并避免了手动释放内存的繁琐操作,从而减少了内存泄漏和野指针的出现。shared_ptr是一个模板类,通过引用计数器实现多个智能指针共享对一个对象的所有权。每次复制一个shared_ptr对象时,该对象的引用计数器会增加1,当最后一个shared_ptr对象被销毁时,引用计数器减1,如果引用计数器变为0,则释放所管理的对象的内存。 阅读详情

相关推荐

三菱FX5U通信之CCLINK操作步骤

11. 连接 CC‐Link 用的端子排,连接 Ver.1.10 对应 CC‐Link 专用电缆。备注:1、以上对应的寄存器都是一一对应的,主站的点数可以比从站多,但是都需要一一对应起来。3.直接安装孔,用于直接安装的螺钉孔(2‐φ4.5,安装螺钉为 M4 螺钉)2.点阵 LED(显示模块中设置的站号和测试模式的内容)5.次段扩展连接器(连接扩展模块的扩展电缆的连接器)4.动作状态(显示 LED 显示模块的动作状态)10 电源连接器,用于连接电源电缆的连接器。1.扩展电缆(扩展时连接用的电缆)

ZXL622722的博客 6931

(C++) share_ptr 之循环引用

unique_ptrshared_ptrweak_ptr都是内存管理中的非常重要的一部分动态内存管理 - cppreference.com。其中shared_ptr在实际应用中具有非常广泛的应用。而由于其较unique_ptr的功能多,有引用计数的概念。导致存在一个名为循环引用的问题。这是一个非常经典的坑。但解决方案也不是很复杂。下面来一起看看吧。

cuber-lotus的博客 2975

centos7部署mysql8.0.35,主从复制,主主集群

centos7 linux部署mysql,主从复制,主主模式

zaixiaqin的博客 1990

智能指针(三)—— shared_ptr 循环引用问题(智能指针什么情况下存在内存泄漏)

智能指针(三)—— shared_ptr 循环引用问题

challenglistic的博客 2970

单片机控制双向可控硅的5种实用触发电路设计(附完整电路图)

本文深入解析了单片机控制双向可控硅的5种实用触发电路设计,涵盖从基础隔离到复杂负载驱动的实战方案。重点探讨了光电耦合器选型、过零检测同步、RC吸收电路精密计算以及应对感性负载和高噪声环境的加固策略,并提供了完整的电路图与调试避坑指南,旨在帮助开发者实现安全可靠的交流负载控制。

joy55的博客 2212

LVI-SAM适配KITTI数据集避坑指南:IMU频率与数据同步问题解析

本文深入解析了将LVI-SAM框架适配KITTI数据集时,在IMU频率与多传感器数据同步方面遇到的核心挑战与解决方案。针对KITTI数据集中sync与extract两种数据包的差异,文章提供了从数据选择、参数调优到时间戳诊断与修复的完整避坑指南,帮助开发者实现稳定高效的SLAM系统部署。

7z8x2c4v6b9的博客 248

shared_ptr-循环引用问题

前文我们阐述了智能指针的思想和进行了简单的实现,当然最后提出了shared_ptr引用计数的线程安全问题,最简单的方式就是通过加锁来进行实现。智能指针内容:C++ 智能指针原理及简单实现那解决了引用计数的问题就可以了吗?其实不然,要使shared_ptr是线程安全的,就还得解决shared_ptr的循环引用的问题。编译环境:vs2013C++11和boost中智能指针的关系(1) C++ 98 中产生了第一个智能指针auto_ptr。

m0_69597277的博客 1304

学Simulink——基于直流电机的建模与控制场景实例:他励直流电机的起动与制动过程仿真

直流电机在工业控制、电动车辆、自动化设备中广泛应用。其中,他励直流电机(Separately Excited DC Motor)因其励磁绕组与电枢绕组分别供电,具有良好的调速性能和启动特性,常用于需要平稳启动和精确控制的场合。在实际应用中,电机的启动过程和制动过程对电网、机械系统以及电机本身都具有重要影响。因此,仿真分析他励直流电机的启动与制动特性,是电机控制设计的重要环节。本文将详细介绍如何使用构建一个他励直流电机的启动与制动过程仿真模型,并通过仿真分析其动态响应。本文详细介绍了如何使用构建一个。

xiaoheshang_123的博客 227

shared_ptr循环引用

循环引用:两个对象相互使用shared_ptr成员变量指向对方造成循环引用,导致引用计数失效。 即A内部有指向B,B内部有指向A,这样对于A,B必定是在A析构后B才析构,对于B,A必定是B析构后才析构A,这就是循环引用的问题,违反常规,导致内存泄露。 示例代码: #include ciostream> #include<nemory> using namespace std; class BB; class AA{ public: shared_ptr<B

chenxijie1985的专栏 4657

数据中台:大数据平台,数据仓库(DM),数据中台之间的联系以及异同分析

大数据平台是一个技术平台。这个技术平台提供了对于大数据的分布式采集,存储,流处理和计算,实时分析等能力。在没有大数据平台前也有数据集成和管理的平台,这种平台可以实现对结构化数据本身的采集,集成和管理。 管理平台,是在原生的大数据生态的基础之上,为了更好的管理集群服务,管理集群的资源,提供灵活SRE能力和资源核算审计能力的一系列工具和合称整体架构数据中台包括数据仓库的全部内容,数据仓库为数据中台提供了数据对外提供服务的基础资源,数据中台将数据仓库建设的投入价值进行最大化,以加快数据赋能业务的速度大家都知道数据

GIS摆渡人 2132

C#上位机性能优化全攻略:彻底解决界面卡顿+多线程死锁+PLC数据延迟,产线实测稳定运行2年

一开始我们用的是网上找的零散优化代码,根本满足不了要求,后来花了2个月的时间,把之前27条产线的代码整理、重构、优化,做了一套这套方案上线后,连续稳定运行2年零3个月:界面响应时间稳定在50ms以内,多线程死锁率持续为0,PLC数据延迟稳定在150ms以内,系统可用率≥99.99%,帮客户一年省下了超过480万的停线损失、罚款损失和人工成本,客户第二年就把剩下的22条产线也全部交给我们做了,还介绍了3家同行。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 294

智能指针std::shared_ptr之循环引用

类的成员变量包含共享指针,假设类的两个实例由共享指针管理,分别称为此实例与彼实例,此实例的共享指针指向彼实例,而彼实例的共享指针指向此实例。 上述情况可以视为,由共享指针管理的外层对象持有内层对象,而内层对象以共享指针形式直接或者间接引用外层对象。 销毁外层对象的前提是内层对象不再引用外层对象,而内层对象在析构之时才解除引用,即必须先销毁外层对象。似此对象之间跨层级相互引用,而无法解除引用关系,形成循环引用。

独孤过的博客 3356

Codex入门00-初识神器(小白入门:到底什么是Codex CLI,和ChatGPT写代码有什么不同?)

OpenAI Codex CLI 是 OpenAI 于2025年推出的终端原生AI编程代理,不是在网页里聊天写代码,而是直接在你的终端里自主读代码、改文件、跑命令。它拥有三种安全模式、/goal 持久化任务、云端沙箱执行等独特能力。本文从零介绍 Codex CLI 的核心概念、与 ChatGPT 写代码的本质区别、典型使用场景和费用说明,让你全面认识这个改变开发方式的神器。

yueyeguzhuo的专栏 302

shared_ptr循环引用问题

weak_ptr是C++标准库中智能指针的一种类型,用于解决循环引用问题和避免悬挂指针(dangling pointer)的情况发生。与shared_ptr不同,weak_ptr并不拥有所指向对象的所有权,它只是对被管理对象的一个观察者。解决循环引用问题:当两个或多个对象相互持有对方的shared_ptr时,形成循环引用。这种情况下,对象的引用计数永远不会变为0,导致内存泄漏。通过使用weak_ptr可以打破循环引用,避免内存泄漏的发生。代码见上面示例;weak_ptr允许你观察由shared_ptr。

wangwl1998的博客 1038

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

shared_ptr创建方式以及循环引用问题

shared_ptr 是 C++ 标准库提供的智能指针,用于管理动态分配的对象,通过引用计数实现资源的自动释放。它是现代 C++ 中避免内存泄漏的核心工具之一。

2301_78992766的博客 945

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

share_ptr循环引用产生原因及其解决方案

根据之前的分析可知,前三句代码执行完后,Person对象的引用计数为1,Car对象的引用计数为2。根据代码执行顺序,share_ptr指针指向new创建的一个Person对象,也就是图中栈空间的person指针指向了堆空间的Person对象,引用计数为1,同理,car指针也指向了堆空间的Car对象,引用计数亦为1。接下来,Person对象里的成员m_car指向Car对象,Car对象的引用计数加1后为2,Car对象的m_person也指向Person对象,Person对象引用计数也加1为2。

木牛的博客 344

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

C++ 浅谈之智能指针 shared_ptr 循环引用

智能指针 shared_ptr 循环引用

优质后端技术知识记录 1523

巧用weak_ptr认识shared_ptr相互引用

智能指针相互引用,如何判断是不是真的没有释放

zengguizhang的博客 918

【C++入门到精通】智能指针 shared_ptr循环引用 | weak_ptr 简介及C++模拟实现 [ C++入门 ]

这篇文章介绍了std::shared_ptr循环引用问题以及解决方案std::weak_ptr。它解释了循环引用的概念,并提供了使用示例和模拟实现方法。通过阅读这篇文章,您将了解循环引用问题以及如何使用std::weak_ptr来解决该问题。

Yawesh的博客 3344

C++智能指针(share_ptr)及其循环引用问题

share_ptr: 智能指针(smart pointer)是存储指向动态分配(堆)对象指针的类,用于生存期控制,能够确保自动正确的销毁动态分配的对象,防止内存泄露。它的一种通用实现技术是使用引用计数(reference count)。智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象共享同一指针。每次创建类的新对象时,初始化指针并将引用计数置为1;当对象作为另一对象的副本...

feikudai8460的博客 3770

C++11:shared_ptr循环引用问题

详细介绍了引用循环出现的场景及为什么会出现引用循环,以及如何解决引用循环,引入了weak的概念。

2201_75880188的博客 1212

c++11/14之std::shared_ptr作为引用参数,普通参数

1. c++中使用std::shared_ptr类型做为构造函数参数,并使用std::move()初始化成员变量。 使用std::shared_ptr类型作为形参,shared_ptr会被复制,使用std::move()之后,形参对象就没有内容了。 #include <iostream> #include <utility> #include <memory&g...

janeqi1987的专栏 1万+

浅谈shared_ptr与循环引用问题

前面对于智能指针已经大致的提过了,但是关于shared_ptr上一篇文章没有仔细分析,这里把它单独拎出来理一理。 前面已经提过由于scoped_ptr(unique_ptr)无法解决让多个对象管理同一块空间的情况,标准库中又追加引用了shared_ptr,而我们的shared_ptr是参考了string类当中的引用计数这个巧妙的方法来解决多个对象管理同一块空间的问题的,而且除此之外我们这里的模拟实现还要考虑跟多一点,就是加入删除器的部分,以适用不同的指针。

chenkaixin_1024的博客 6160

shared_ptr循环引用的例子及解决方法示例

之前看到循环引用的时候,总是只能看到一个很简单的例子,我觉得挺没意思,因为没有实际的意义,就想找个好点的例子来分享。 所以,这篇文章将专注于展示一个更实际点的例子来说明实际工作中确实会碰到shared_ptr的循环引用的问题,然后再展示如何使用weak_ptr来解决。

Jacketinsysu的专栏 8215
上一篇: 【C++模板友元深度解析】:掌握泛型编程中的高级访问控制技巧
下一篇: 【Entity Framework Core迁移命令全攻略】:掌握高效数据库版本控制的5大核心技巧
codetrick
博客等级 码龄17年 151粉丝 1991原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值