当前位置: 首页 > news >正文

C++智能指针循环引用破解

C++智能指针循环引用破解

智能指针在管理动态内存时可能遇到循环引用问题,导致内存泄漏。weak_ptr是打破循环引用的关键工具,它不增加引用计数。

循环引用发生在两个对象互相持有shared_ptr。

#include
#include
#include
#include

struct LeakyNode {
std::string name;
std::shared_ptr next;

explicit LeakyNode(const std::string& n) : name(n) {
std::cout << "LeakyNode " << name << " created\n";
}

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

void circular_reference_problem() {
auto a = std::make_shared("A");
auto b = std::make_shared("B");

a->next = b;
b->next = a;

std::cout << "Reference counts:\n";
std::cout << "a use_count: " << a.use_count() << "\n";
std::cout << "b use_count: " << b.use_count() << "\n";
}

shared_ptr循环引用导致内存泄漏。

struct Node {
std::string name;
std::shared_ptr next;
std::weak_ptr prev;

explicit Node(const std::string& n) : name(n) {
std::cout << "Node " << name << " created\n";
}

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

void weak_ptr_break_cycle() {
auto a = std::make_shared("A");
auto b = std::make_shared("B");

a->next = b;
b->prev = a;

std::cout << "a use_count: " << a.use_count() << "\n";
std::cout << "b use_count: " << b.use_count() << "\n";

if (auto locked = b->prev.lock()) {
std::cout << "b's prev: " << locked->name << "\n";
}
}

weak_ptr的lock方法获取临时shared_ptr。

void weak_ptr_methods() {
auto shared = std::make_shared(42);
std::weak_ptr weak(shared);

if (auto locked = weak.lock()) {
std::cout << "Locked value: " << *locked << "\n";
std::cout << "Expired: " << weak.expired() << "\n";
}

shared.reset();

if (weak.expired()) {
std::cout << "weak_ptr expired\n";
}
}

二叉树使用weak_ptr避免循环。

struct TreeNode {
int value;
std::shared_ptr left;
std::shared_ptr right;
std::weak_ptr parent;

explicit TreeNode(int v) : value(v) {
std::cout << "TreeNode " << value << " created\n";
}

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

std::shared_ptr get_parent() const {
return parent.lock();
}
};

void tree_example() {
auto root = std::make_shared(1);
auto left = std::make_shared(2);
auto right = std::make_shared(3);

root->left = left;
root->right = right;
left->parent = root;
right->parent = root;

if (auto p = left->get_parent()) {
std::cout << "Parent of left child: " << p->value << "\n";
}
}

enable_shared_from_this解决this获取shared_ptr的问题。

class AsyncOp : public std::enable_shared_from_this {
int id_;
public:
explicit AsyncOp(int id) : id_(id) {}

std::shared_ptr get_shared() {
return shared_from_this();
}

void start() {
auto self = shared_from_this();
std::thread([self]() {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::cout << "AsyncOp " << self->id_ << " completed\n";
}).detach();
}

int id() const { return id_; }
};

void enable_shared_example() {
auto op = std::make_shared(42);
op->start();
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}

weak_ptr在缓存系统中的应用。

template
class Cache {
std::map> cache_;
std::mutex mtx_;

public:
std::shared_ptr get(const K& key) {
std::lock_guard lock(mtx_);
auto it = cache_.find(key);
if (it != cache_.end()) {
if (auto ptr = it->second.lock()) {
std::cout << "Cache hit for " << key << "\n";
return ptr;
}
}
return nullptr;
}

void insert(const K& key, std::shared_ptr value) {
std::lock_guard lock(mtx_);
cache_[key] = value;
}

size_t size() const {
std::lock_guard lock(mtx_);
return cache_.size();
}
};

void cache_demo() {
Cache cache;
auto s = std::make_shared("cached_value");
cache.insert(1, s);

auto result = cache.get(1);
if (result) {
std::cout << "Got: " << *result << "\n";
}

s.reset();
result = cache.get(1);
if (!result) {
std::cout << "Expired entry removed\n";
}
}

weak_ptr不干扰引用计数,不阻止对象销毁。

void weak_ptr_lifecycle() {
std::weak_ptr weak;

{
auto shared = std::make_shared(100);
weak = shared;
std::cout << "Inside scope, expired: " << weak.expired() << "\n";
}

std::cout << "Outside scope, expired: " << weak.expired() << "\n";
}

使用weak_ptr正确管理对象生命周期,避免循环引用导致的内存泄漏。

http://www.jsqmd.com/news/1028874/

相关文章:

  • 2026广州海珠区名表回收店铺,浪琴万国全套加价收 - 逸程
  • 近协议网关深度解析:从二进制流到统一MQTT消息的工程实践
  • 2026宜宾本地承载力检测哪家专业?高口碑TOP 正规机构榜单 + 联系方式+ 实地测评 - 中安检测集团
  • 如何用SENAITE LIMS在30分钟内搭建专业实验室管理系统?
  • QorIQ T系列处理器深度解析:架构、DPAA与电源管理实战
  • 乌海黄金回收实测|正规实体老店,全城免费上门无套路✨ - 行行星
  • 2026宁波本地噪音检测哪家专业?TOP 正规机构榜单 + 环境噪声 + 工业噪音 + 低频噪音检测 附电话地址 - 鉴安检测
  • 2026松原业主高频选择的 5 家专业验房检测机构实地测评整理 毛坯验房 + 精装验房 + 空鼓开裂检测 附电话地址 - 科信检测
  • 2026辽阳本地噪音检测哪家专业?TOP 正规机构榜单 + 环境噪声 + 工业噪音 + 低频噪音检测 附电话地址 - 鉴安检测
  • 无需纯化,直接在天然环境中玩转分子互作
  • 徐州鼓楼区黄金回收简报:本地行情与六家机构服务概览 - 上门黄金回收
  • 统信UOS任务栏进阶玩法:从基础布局到效率提升全攻略
  • Java计算机毕设之基于 SpringBoot+Vue 的数码商城订单与会员管理系统设计 数字化消费场景下数码产品购物商城的设计与研发(完整前后端代码+说明文档+LW,调试定制等)
  • 2026天津本地环评检测哪家专业?TOP 正规机构榜单+环境监测 + CMA 检测 + 环保验收 附电话地址 - 中检检测集团
  • MPC8548E硬件加密引擎SEC 2.1:原理、集成与性能调优实战
  • ZFX山海证券:“甲骨文云需求推升目标价”
  • 重庆闲置女款积家约会腕表,近期回收行情怎么样? - 讯息早知道
  • 手机号码定位查询:3分钟学会免费获取地理位置信息的终极指南
  • 2026山南本地环评检测哪家专业?TOP 正规机构榜单+环境监测 + CMA 检测 + 环保验收 附电话地址 - 中检检测集团
  • 延迟直降90%!国标GB28181视频平台EasyGBS支持WebRTC WHIP推流设备接入,让万物互联更简单
  • 一篇文章讲透PLM产品生命周期管理!(3000+字)
  • 长沙卖黄金必懂10个高频问题,一次性讲透避坑逻辑 - 逸程
  • 绍兴上虞区黄金上门回收,足不出户轻松变现 - 专业黄金回收
  • 2026南平本地环评检测哪家专业?TOP 正规机构榜单+环境监测 + CMA 检测 + 环保验收 附电话地址 - 中检检测集团
  • 特性开关动态编排:从硬编码到策略驱动
  • 2026免费在线去除背景工具保姆级教程!无需下载高清无水印AI抠图全方法 - AI测评专家
  • ePAPR虚拟化标准:嵌入式Power架构的Hypercall与中断管理详解
  • 从集采到销售:多组织集团如何用ERP实现业务闭环?
  • 北京分手协议履行纠纷律所指南:书面约定反悔后如何依法维权? - 品牌2026
  • ArduinoFFT终极指南:5个步骤掌握Arduino信号频谱分析