std::out_ptr是为c api输出参数设计的raii封装器,不接管所有权也不做类型转换;误当智能指针转换器用会导致崩溃或泄漏,仅适用于t**形参且c函数malloc后写入新地址的场景。
std::out_ptr 不能直接配合 C 风格 API 使用——它本身不是“转换工具”,而是为“输出参数”场景设计的 RAII 封装器,用错就崩溃或内存泄漏。
std::out_ptr 是什么,为什么不能当“智能指针转换器”用
它不接管原始指针所有权,也不做类型转换;它只是在函数调用前后自动把 std::unique_ptr 或 std::shared_ptr 的裸指针地址传给 C 函数,并在调用后根据需要重置智能指针(比如 C 函数 malloc 了新内存并写入指针地址)。常见误解是把它当成 std::unique_ptr → T* 的安全转换接口,其实不是。
容易踩的坑:
- 对只读 C 函数(如
void inspect(const Foo*))误用std::out_ptr:它会试图解引用并赋值,导致未定义行为 - 传给非
T**类型的参数(比如void**或int**),编译失败或静默错误 - C 函数没按约定写入新地址,但
std::out_ptr仍调用reset(),导致原资源被提前释放
正确配合 C API 的典型场景:输出参数 + malloc 分配
适用于 C 函数形如 int create_foo(Foo** out_foo),且内部调用 malloc 或等效分配,并将结果写入 *out_foo。
立即学习“C++免费学习笔记(深入)”;
实操建议:
- 确保 C 函数签名明确接收
T**,且文档/头文件说明它会写入新分配对象 - 用
std::unique_ptr初始化为空,再传std::out_ptr(ptr) - 检查 C 函数返回值,失败时
ptr应保持为空,避免误reset
示例: