从同一原始指针创建多个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
相关产品推荐
相关产品推荐

