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

从同一原始指针创建多个unique_ptr为何无编译错误?

为什么多个unique_ptr指向同一变量能编译通过?

嘿,这个问题问到点子上了!很多刚上手智能指针的同学都会有这个疑惑——明明unique_ptr的核心是独占对象所有权,怎么我写了多个unique_ptr指向同一块内存,编译器却没报错?

首先得肯定你的基础理解:unique_ptr的设计目标就是保证同一时间,只有一个智能指针拥有对目标对象的所有权,这也是它名字里“unique”的由来。那为啥编译能过?咱拆成两点说:

1. 编译器只做语法/类型检查,不做逻辑校验

编译器的职责是确保代码符合语言语法规则、类型匹配,但它不会去预判你运行时的逻辑错误。比如你用原始指针构造unique_ptr的时候,只要你传的参数是一个合法的指针类型(比如int*对应unique_ptr<int>),编译器就会认为这个构造操作是合法的——它不会去检查“这个指针是不是已经被另一个unique_ptr接管了”。

就拿你给出的代码(我补全了main函数里的核心逻辑)来说:

#include <iostream>
#include <memory>
using namespace std;

int main() {
    int num = 10;
    unique_ptr<int> ptr1(&num);
    unique_ptr<int> ptr2(&num); // 这里同时用同一个地址构造两个unique_ptr
    
    cout << *ptr1 << endl;
    cout << *ptr2 << endl;
    return 0;
}

这段代码完全符合C++语法,类型也匹配,所以编译器会顺利通过。

2. 但这是严重的未定义行为!

编译通过不代表代码正确!这段代码运行起来大概率会出问题:

  • 当main函数执行完毕,ptr1和ptr2都会触发析构函数,尝试调用delete去释放它们指向的内存。
  • 如果你的变量是栈上的(比如示例里的num),delete栈内存本身就是非法操作;如果是堆上的变量,两次delete会导致双重释放,直接触发程序崩溃,或者出现不可预料的内存错误。

正确使用unique_ptr的姿势

要遵守unique_ptr的独占规则,正确的做法是:

  • 从对象创建时就用unique_ptr接管所有权,优先用make_unique(C++14及以上):
    unique_ptr<int> ptr1 = make_unique<int>(10);
    
  • 如果需要转移所有权,必须用std::move,转移后原unique_ptr会变成空的:
    unique_ptr<int> ptr2 = move(ptr1);
    // 此时ptr1已经不再拥有对象所有权,不能再访问*ptr1
    

记住:智能指针是用来帮你管理内存 _,但 Jud关注这account -需品样式收到 affirming基础信息Read 我刚才的想法是对的,编译器不会替你兜底逻辑错误哦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:21:09