指向unique_ptr的指针 - 这是一个漏洞吗?

Pointer to unique_ptr - is this a loophole?

本文关键字:一个 漏洞 ptr unique 指针 指向      更新时间:2023-10-16

绕过unique_ptr的简单方法似乎是使用指向unique_ptr对象的指针。这并不难。所以使用unique_ptr是一种君子协议,而不是真正超级强制执行?

#include <iostream>
#include <memory>
using namespace std;
class Box {
public:
int num;
};
void update_box(unique_ptr<Box>* pu);
int main(){
unique_ptr<Box> b{new Box};
unique_ptr<Box>* u = &b;
update_box(u);
cout << b->num << endl; // Outputs 99.
return 0;
}
void update_box(unique_ptr<Box>* pu) {
(*pu)->num = 99;
}

从某种意义上说,C++充满了君子协议。换句话说,语言让你有能力搬起石头砸自己的脚。

没有什么可以阻止您获取std::unique_ptr的地址。如果你真的觉得这令人反感,那么你可以从std::unique_ptr继承,并使用包含静态断言的函数重载 address-of 运算符。

但即使你这样做了,你也可以用std::addressof来规避它!

你实际上把你真正的问题放在评论中:

我对unique_ptr的理解是,它应该用于确保在任何时候只有一个指向对象的指针。

不,这是错误的。您可以轻松地执行一个简单的操作:

std::unique_ptr<int> a(new int);
int *b = a.get(); // b points to the same object as a

unique_ptr的设计试图确保一个对象只能有一个unique_ptr。但即使如此,它只有在不使用裸指针的情况下才能确保这一点。使用裸指针,很容易避开此设计:

std::unique_ptr<int> a(new int);
std::unique_ptr<int> b(a.get());

在这里,b指向与a相同的对象,因此该程序具有未定义的行为(因为int对象将被删除两次(。

unique_ptr的意图是显示所有权。由于只能有一个unique_ptr可以指向一个对象(忽略我之前介绍的"hack"(,unique_ptr拥有指向的对象,并且当调用unique_ptr的析构函数时,它将删除指向的对象。

我知道这是由多个人回答的。但我想提到的是,可能存在需要传递unique_ptr引用的真实用例。

考虑以下示例:

StatusMsg getMemory(unique_ptr<char[]>& Up) {
unique_ptr<char[]> mem(new char[100]);
Up = std::move(mem);
return StatusMsg::Success;
}
int main() {
unique_ptr<char[]> Up;
StatusMsg s = getMemory(Up);
if (s!=StatusMsg::Success) {
// throw error
}

// Do something with allocated memory
}

在这里,必须使用引用调用返回(或更新(unique_ptr,因为实际返回值应该是状态 msg。