You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

按值返回std::unique_ptr是否安全?std::shared_ptr是否支持相同用法?

分析你的代码与问题

首先直接给出结论:按值返回std::unique_ptr是完全安全且符合规范的用法,你的担心是多余的,而且ptr1会在main函数结束离开作用域时才被销毁,不会提前消失。不过你的代码里有一个关键错误需要先修正,我们一步步拆解:

1. 你的代码中的致命问题

你用std::unique_ptr<wchar_t>管理动态数组(new wchar_t[len]),但默认的unique_ptr删除器是delete,而非适配数组的delete[]!这会导致数组内存无法被正确释放,触发未定义行为(比如内存泄漏、程序崩溃)。

正确的做法是使用数组特化版本的unique_ptr:std::unique_ptr<wchar_t[]>,它会自动用delete[]释放内存:

std::unique_ptr<wchar_t[]> mem::TO_WCHAR_T_PTR(char* str) {
    size_t len = strlen(str) + 1;
    std::unique_ptr<wchar_t[]> wStr_ptr(new wchar_t[len]); // 数组特化版本
    size_t convertedChars = 0;
    mbstowcs_s(&convertedChars, wStr_ptr.get(), len, str, _TRUNCATE);
    return wStr_ptr;
}

2. 按值返回unique_ptr为什么安全?

你提到的移动语义正是核心原因:

  • 当按值返回unique_ptr时,编译器会自动触发移动构造(甚至会通过返回值优化RVO直接在目标位置构造对象,连移动操作都能省掉),不会执行拷贝(unique_ptr的拷贝构造函数是被删除的,本来就不允许拷贝)。
  • 返回后,ptr1会接管wStr_ptr持有的内存所有权,原wStr_ptr会变成空状态,不再持有内存。当ptr1离开main的作用域时,unique_ptr的析构函数会自动调用对应删除器(数组版本就是delete[])释放内存,完全符合预期。

所以你完全不用担心ptr1提前被销毁,它的生命周期和普通变量一致,只会在作用域结束时被清理。

3. 这种用法对shared_ptr同样适用吗?

当然适用!

  • shared_ptr本身支持拷贝,按值返回时会自动增加引用计数,返回后的目标对象(比如auto ptr = func();)会持有新的引用,原临时返回值的引用计数会自动减少(如果是临时对象,编译器甚至会直接优化掉中间步骤)。
  • 同样,如果用shared_ptr管理动态数组,C17及以后支持std::shared_ptr<wchar_t[]>的数组特化,无需手动指定删除器;如果是更早的C标准,需要显式指定delete[]作为删除器:
std::shared_ptr<wchar_t> wStr_ptr(new wchar_t[len], std::default_delete<wchar_t[]>());

总结

  • 按值返回智能指针(不管是unique_ptr还是shared_ptr)都是标准且安全的用法,完全符合C++的设计意图。
  • 一定要注意智能指针的数组特化版本,避免用错删除器导致内存问题。

内容的提问来源于stack exchange,提问作者AidenDean

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 13:42:29