当前位置: 首页 > 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.gsyq.cn/news/1540755.html

相关文章:

  • QorIQ T系列处理器深度解析:架构、DPAA与电源管理实战
  • 乌海黄金回收实测|正规实体老店,全城免费上门无套路✨ - 行行星
  • 2026宁波本地噪音检测哪家专业?TOP 正规机构榜单 + 环境噪声 + 工业噪音 + 低频噪音检测 附电话地址 - 鉴安检测
  • 2026宜宾本地承载力检测哪家专业?高口碑TOP 正规机构榜单 + 联系方式+ 实地测评 - 中安检测集团
  • 2026松原业主高频选择的 5 家专业验房检测机构实地测评整理 毛坯验房 + 精装验房 + 空鼓开裂检测 附电话地址 - 科信检测
  • 2026天津本地环评检测哪家专业?TOP 正规机构榜单+环境监测 + CMA 检测 + 环保验收 附电话地址 - 中检检测集团
  • 无需纯化,直接在天然环境中玩转分子互作
  • ZFX山海证券:“甲骨文云需求推升目标价”
  • 延迟直降90%!国标GB28181视频平台EasyGBS支持WebRTC WHIP推流设备接入,让万物互联更简单
  • 2026山南本地环评检测哪家专业?TOP 正规机构榜单+环境监测 + CMA 检测 + 环保验收 附电话地址 - 中检检测集团
  • 重庆闲置女款积家约会腕表,近期回收行情怎么样? - 讯息早知道
  • 北京分手协议履行纠纷律所指南:书面约定反悔后如何依法维权? - 品牌2026
  • 【录取率TOP1】四川普华教育2027届单招培训火热报名中...... - 四川单招培训
  • 杭州黄金回收实测:5家门店套路拆解与避坑指南 - 奢侈品回收评测
  • 2026南宁业主高频选择的 5 家专业验房检测机构实地测评整理 毛坯验房 + 精装验房 + 空鼓开裂检测 附电话地址 - 科信检测
  • 2026北京出手欧米茄别踩坑!为何别人能多卖上千? - 逸程
  • 天津黄金回收门店排行榜|禹竞名奢汇稳居榜首,本地变现首选不踩坑 - 名奢变现站
  • 遗失登报怎么办理?一文给你讲清楚! - 慧办好
  • USDPAA架构下PPAC/PPAM设计:用户态数据包处理的高性能实践
  • 银河麒麟 V10 重装打印服务 (CUPS)+ 打印机驱动完整教程
  • GAN合成数据:工业级可控生成原理与实战指南
  • 2026太原搬家公司 避坑TOP5测评 长短途搬家闭眼选 - LYL仔仔
  • 2026快手保存无水印视频教程,快手视频去水印方法官方合规指南,第三方快手去水印工具风险详解 - 科技热点发布
  • 临沂市本土黄金白银铂金彩金回收品牌实力排行更新,从报价到服务全测评,实力领跑同行以及联系方式推荐 - 亦辰小黄鸭
  • 三明市闲置黄金白银铂金彩金回收变现全攻略 五家靠谱实体回收店深度解析+2026实时金价+避坑实战案例及联系方式 - 前途无量YY
  • 2026泰州电商企业做GEO应该怎么选服务商?本地靠谱GEO服务商推荐及选型实战解析 - 科技快讯
  • MPC8536E/MPC8535E SEC 3.0硬件加密引擎实战:原理、集成与性能优化
  • 三亚市闲置黄金白银铂金彩金回收变现全攻略 五家靠谱实体回收店深度解析+2026实时金价+避坑实战案例及联系方式 - 前途无量YY
  • MCP1612同步降压控制器:从原理到PCB布局的完整电源设计指南
  • Open Library完整指南:如何快速构建全球最大的免费数字图书馆