shared_ptr应优先用make_shared初始化以避免双重分配和异常不安全;多个shared_ptr共享同一对象和控制块,引用计数管理所有权;循环引用需用weak_ptr破环;严禁混用shared_ptr与裸指针操作同一内存。

shared_ptr 初始化必须用 make_shared 或 new,不能直接构造裸指针
直接用 shared_ptr 虽然能编译,但有双重内存分配开销(控制块和对象分开分配),且异常不安全。推荐统一用 make_shared:
-
auto p = std::make_shared—— 一次分配,高效安全(42); -
auto p = std::make_shared<:string>("hello");—— 支持完美转发构造参数 - 若必须用
new(比如需要自定义删除器),至少用显式构造:shared_ptrp(new int(42), [](int* ptr){ delete ptr; });
shared_ptr 的拷贝和赋值会增加引用计数,不是深拷贝
多个 shared_ptr 可以指向同一块内存,它们共享同一个控制块。这不是复制对象内容,而是共享所有权:
auto a = std::make_shared(100); -
auto b = a;→ 此时引用计数变为 2,*a和*b都是 100 -
a.reset();后,引用计数减为 1,对象仍存活;只有最后一个shared_ptr析构或reset()时才会调用删除器
循环引用问题:weak_ptr 是 shared_ptr 的“解药”
两个 shared_ptr 相互持有(如父子节点、观察者模式),会导致引用计数永远不归零,内存泄漏:
- 典型错误:
struct Node { std::shared_ptrparent; std::shared_ptr child; }; - 修复方式:把其中一个改为
std::weak_ptr,它不增加引用计数,访问前需调用lock(): auto safe_ptr = weak_ptr.lock(); if (safe_ptr) { /* 使用 safe_ptr */ }
不要混用 shared_ptr 和裸指针操作同一块内存
这是最危险的误用,极易导致 double-free 或悬空指针:
立即学习“C++免费学习笔记(深入)”;
- ❌ 错误:
int* raw = new int(5); auto p1 = shared_ptr—— 控制块独立,析构两次(raw); auto p2 = shared_ptr (raw); - ❌ 错误:
auto p = std::make_shared—— 手动释放后,(5); delete p.get(); p析构再释放一次 - ✅ 安全做法:裸指针仅用于观察(
p.get()),所有所有权管理交由shared_ptr实例负责
智能指针本身不难,真正容易出问题的是所有权边界的模糊——比如该传 shared_ptr 还是 const shared_ptr&,函数返回时该 move 还是 copy,这些细节在跨模块或生命周期复杂的场景里,稍不注意就会埋下隐患。










