我有以下简单的代码,我没有找到一个线程,其中智能指针用于这个简单的情况,而是复制对象:
int main()
{
int i = 1;
std::unique_ptr<int> p1(&i);
*p1 = 2;
return 0;
}
当指针超出范围时,这会导致_BLOCK_TYPE_IS_INVALID
。如果我调用p1.release()
,代码工作正常,我不会收到此错误。我认为这样的指针很聪明,可以处理悬空指针吗?
另一种选择是,如果我有i的副本,它不会产生上述错误:
std::unique_ptr<int> p1(new int(i));
在这里使用智能指针有什么好处,我不想执行本地副本?
如果我要使用原始指针:
int i = 1;
int *p1 = &i;
*p1 = 2;
即使我没有代码,我也不会收到错误:
p1 = nullptr;
答案 0 :(得分:9)
std::unique_ptr
用于处理动态分配的内存;当你构建指针时,他们会说取得指针的所有权。
你的int i;
在堆栈中,因此没有动态分配;它的所有权不能从堆栈中拿走。当unique_ptr
析构函数尝试delete
你给它的指针(因为它认为没有人拥有它)时,你会得到该错误,因为delete
只能用于用{{new
创建的指针1}}。
鉴于你的简短例子,我不知道它在哪个上下文......但你应该使用原始指针(或者如你所说的那样复制)用于堆栈分配的变量。
答案 1 :(得分:0)
@qzx提供的答案是您在代码中报告的问题的主要原因
关于std::unique_ptr<>
使用的另一个问题。您应该始终尝试使用std::make_unique<>()
来创建std::unique_ptr
。它有时通过提供适当的编译错误来帮助适当地使用此指针。
例如,如果您将上述代码更改为std::make_unique<>
int i = 1;
std::unique_ptr<int> p1 = make_unique<int>(&i);
然后大多数编译器会给出错误
can't convert int* to int
它将帮助您使用一个副本,该副本创建一个全新的整数,其所有权由std::unique_ptr<>
int i = 1;
std::unique_ptr<int> p1 = make_unique<int>(i);
*p1 = 2;
此代码有效。