面试题:两段shared_ptr代码哪种更优?第一种存在什么问题?
代码实现对比与最优方案解析
结论:第二段写法比第一段更安全,而最优实现是使用std::make_shared,下面具体分析:
第一段代码的风险
第一段代码:
int* a = new int(); shared_ptr<int> sh(a);
这里存在两个核心问题:
- 内存泄漏隐患:从
new int()创建裸指针,到将其交给shared_ptr管理的这段区间,如果后续修改代码时插入了抛异常的逻辑,裸指针a会失去被智能指针接管的机会,直接导致内存泄漏。 - 裸指针误用风险:裸指针
a可以被其他代码随意访问,比如被手动delete,或者被传递给另一个shared_ptr,这会触发重复释放的未定义行为,直接导致程序崩溃。
第二段代码的改进
第二段代码:
shared_ptr<int> sh(new int());
这种写法消除了裸指针暴露的问题,new int()的结果直接作为shared_ptr构造函数的参数,中间没有可被误用的裸指针变量,安全性比第一段高很多。但它仍有一个性能缺陷:shared_ptr需要两块独立内存——一块存对象本身,一块存引用计数等控制块。这里new int()分配对象内存,shared_ptr构造时再分配控制块,两次内存分配会带来额外的开销。
最优方案:std::make_shared
面试官提到的make_shared才是真正的最优解,写法如下:
auto sh = make_shared<int>();
它的优势体现在:
- 极致安全:全程没有裸指针暴露,对象的分配和智能指针的绑定由标准库原子性完成,完全杜绝了中间环节异常导致的内存泄漏。
- 性能更优:
make_shared会一次性分配一块连续内存,同时存放对象和shared_ptr的控制块,减少了一次内存分配操作,降低了内存开销和碎片化概率。
内容的提问来源于stack exchange,提问作者Tej Ravi
相关产品推荐
相关产品推荐

