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

传入原始指针构造unique_ptr时的地址一致问题及相关疑问

std::unique_ptr常见疑问解答

示例代码

#include <iostream>
#include <memory>

class foo{
    int x;
public:
    foo(): x(0) {}
    foo(int a): x(a) {}
    foo(const foo& f): x(f.x) {}
};

int main(){
    foo *ptr = new foo(5);
    std::unique_ptr<foo> uptr(ptr);
    std::cout << ptr << "\n";
    std::cout << uptr.get() << "\n";
    return 0;
}

输出结果

0x5c7bc80
0x5c7bc80

疑问解答

  1. 是否是将原始指针传入了拷贝构造函数?unique_ptr的拷贝构造函数不是被删除(=delete)了吗?为何原始指针与unique_ptr的地址相同?
    这不是调用拷贝构造函数,unique_ptr的拷贝构造确实已被删除。你这里调用的是unique_ptr的转换构造函数(接受原始指针的重载版本)。地址相同是因为unique_ptr本质是封装了原始指针的容器,get()方法就是返回它内部保存的原始指针值,所以两者指向的内存地址自然一致。需要注意:此时原始指针的所有权已经转移给unique_ptr,之后不能再用ptr去操作这块内存(比如手动delete),否则会触发双重释放的未定义行为。

  2. 这是unique_ptr的设计缺陷吗?
    完全不是设计缺陷。unique_ptr的独占所有权是指禁止多个unique_ptr共享同一块内存的所有权,而非禁止原始指针与unique_ptr指向同一块内存。这种情况是你自己主动保留了原始指针导致的,unique_ptr的设计要求一旦将原始指针交给它管理,就不应再手动持有该原始指针。

  3. 如何解决该问题?
    最安全的解决方式是避免手动创建原始指针,直接使用std::make_unique创建unique_ptr,从源头杜绝重复持有指针的问题:

std::unique_ptr<foo> uptr = std::make_unique<foo>(5);

如果必须使用已有的原始指针构造unique_ptr,构造完成后立刻将原始指针置空,避免后续误操作:

foo *ptr = new foo(5);
std::unique_ptr<foo> uptr(ptr);
ptr = nullptr; // 置空原始指针,防止误操作
  1. std::make_unique()的作用是什么?我尝试将构造语句改为std::unique_ptr uptr(std::make_unique(ptr));但结果未变。
    std::make_unique是C++14引入的工具函数,核心作用是
    安全、便捷地创建unique_ptr*:它会在内部自动完成new操作,返回管理新对象的unique_ptr,既避免了手动写new的繁琐,也能规避内存泄漏、异常安全等问题。

你之前的用法是错误的:std::make_unique<foo>(*ptr)是拷贝ptr指向的对象,创建一个全新的foo实例,返回的unique_ptr管理的是这个新对象,而非接管ptr指向的原有对象。如果你想让unique_ptr接管已有原始指针,直接用std::unique_ptr<foo> uptr(ptr)即可(记得构造后置空ptr);如果是创建新对象,正确用法是std::make_unique<foo>(5),直接传递构造参数,无需手动处理指针。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 19:55:17