news 2026/6/17 9:40:43

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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正确管理对象生命周期,避免循环引用导致的内存泄漏。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/17 9:38:30

DISC性格色彩:从理论到实战,打造高效沟通与协作的底层逻辑

1. DISC性格色彩理论的核心框架 DISC理论将人的行为风格划分为四种基本类型&#xff1a;支配型(D)、影响型(I)、稳健型(S)和谨慎型(C)。这套体系最早由美国心理学家威廉莫尔顿马斯顿在20世纪20年代提出&#xff0c;最初用于研究普通人群的情绪反应模式。经过近百年的发展&#…

作者头像 李华
网站建设 2026/6/17 9:32:31

近协议网关深度解析:从二进制流到统一MQTT消息的工程实践

近协议网关深度解析:从二进制流到统一MQTT消息的工程实践 1. 概述:什么是近协议网关 “近协议网关”是指在物联网接入层中,位于车辆终端与云端消息中间件之间的轻量级协议转换组件。它负责将终端侧的原生二进制协议(如JT/T 808、GB/T 32960)透明地转换为基于MQTT主题发布…

作者头像 李华
网站建设 2026/6/17 9:17:03

3分钟生成专业短视频:终极免费AI视频生成神器MoneyPrinterTurbo

3分钟生成专业短视频&#xff1a;终极免费AI视频生成神器MoneyPrinterTurbo 【免费下载链接】MoneyPrinterTurbo 利用AI大模型&#xff0c;一键生成高清短视频 Generate short videos with one click using AI LLM. 项目地址: https://gitcode.com/GitHub_Trending/mo/MoneyP…

作者头像 李华
网站建设 2026/6/17 9:11:40

Trae:字节跳动推出的 AI 原生 IDE

一、什么是 Trae&#xff1f;Trae 是字节跳动推出的一款 AI 原生集成开发环境&#xff08;IDE&#xff09;&#xff0c;定位与 Cursor 类似&#xff0c;但更加注重&#xff1a;中文开发场景AI Agent 自动开发多模型协同企业级应用开发它并不是简单地给 VS Code 加一个聊天框&am…

作者头像 李华
网站建设 2026/6/17 9:02:12

OpCore Simplify:革命性的黑苹果自动化配置工具

OpCore Simplify&#xff1a;革命性的黑苹果自动化配置工具 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 在普通PC上安装macOS一直是技术爱好者面临…

作者头像 李华