《C++ 智能指针:长达数十年的血泪史,一步步征服内存泄漏》-CSDN博客
shared_ptr<int> sp1(new int(10));
这句代码实际存在两个内存开辟,一是开辟我们要托管的内存资源 ,二是开辟引用计数的资源,引用技术也是new出来的。它们两个是单独new出来的,在不同的内存空间。
如果new int(10)成功了,new引用计数没有成功,那么就意味着shared_ptr对象创建失败了!就不会调用析构函数再释放资源了。所以就会导致资源泄漏,存在这个风险。
shared_ptr<int> sp2 = make_shared<int>(10);// auto sp2 = make_shared<int>(10);
把我们需要托管的内存资源和存储引用计数的内存资源一起开辟了,在一块内存上,去new一次!所以,要么都开辟成功,要么都开辟失败,如果失败了,由于不存在资源的开辟即不存在资源的泄漏。
优点:
- 内存分配效率高
- 防止资源泄漏的风险
缺点:
- 无法自定义删除器
- 导致托管的资源延迟释放
理解shared_ptr托管资源延迟释放的问题
- 如果为shared_ptr
当最后一个使用资源的shared_ptr对象要析构时,强智能指针引用计数uses--为0,就会立即将资源释放,即使此时弱智能指针weaks不为0还在观察。因为托管的资源和存储引用计数的资源不在同一块内存。
- 如果为make_shared
当强智能指针引用计数--为0要释放资源时,如果此时weaks不为0,那么就不能将资源释放,因为它们是同一块内存开辟出来的,即现在没有shared_ptr指向资源了,资源也无法释放。只有当weaks也为0时,才能将资源释放。
使用C++14make_shared代替shared_ptr,使用C++14make_unique代替unique_str。