C++ 简单的唯一问题

C++ 简单的唯一问题,c++,c++11,C++,C++11,为什么我会得到运行时错误,而foo打印出来只是巧合吗 std::unique_ptr<std::string> foo_ptr(new std::string("foo")); foo_ptr.reset(foo_ptr.get()); std::cout << *foo_ptr << std::endl; //prints "foo" so obj hasn't been deleted //runtime error: "pointer being fre

为什么我会得到运行时错误,而foo打印出来只是巧合吗

std::unique_ptr<std::string> foo_ptr(new std::string("foo"));
foo_ptr.reset(foo_ptr.get());
std::cout << *foo_ptr << std::endl; //prints "foo" so obj hasn't been deleted
//runtime error: "pointer being freed was not allocated"
此行将释放foo_ptr中的当前指针,并将其设置为foo_ptr.get的值。由于foo_ptr.get是在更新值之前获取的,因此它指向旧位置

不要这样做。它会导致未定义的行为。您永远不应该使用与重置相同的值调用重置

此行将释放foo_ptr中的当前指针,并将其设置为foo_ptr.get的值。由于foo_ptr.get是在更新值之前获取的,因此它指向旧位置


不要这样做。它会导致未定义的行为。您永远不应该使用与重置相同的值调用重置

引用N337620.7.1.2.5/4和5。

效果:将p指定给存储指针,然后如果未指定存储指针的旧值old_p 等于nullptr,调用get_deleterold_p

[注:这些操作的顺序非常重要 因为打电话给删除者可能会毁掉这个。-结束注意]

因此,取消对该指针的引用会导致未定义的行为。

后置条件:get==p。 [注意:如果调用get\u deleter,则后置条件不起作用


由于此->get不再是有效的表达式,因此销毁*此表达式。-结束说明]

引用n3376 20.7.1.2.5/4和5。

效果:将p指定给存储指针,然后如果未指定存储指针的旧值old_p 等于nullptr,调用get_deleterold_p

[注:这些操作的顺序非常重要 因为打电话给删除者可能会毁掉这个。-结束注意]

因此,取消对该指针的引用会导致未定义的行为。

后置条件:get==p。 [注意:如果调用get\u deleter,则后置条件不起作用


由于此->get不再是有效的表达式,因此会销毁*它。-结束说明]

这是未定义的行为。任何事情都有可能发生。该程序在第3行不再是有效程序。是的,这是巧合。事实上,这是一个鼻恶魔。顺便说一句:知道某个东西是否被破坏的更好方法是创建一个类,在它的析构函数上打印某个东西。这是未定义的行为。任何事情都有可能发生。该程序在第3行不再是有效程序。是的,这是巧合。事实上,它是一个鼻恶魔。顺便问一下:要知道某个东西是否被破坏,最好的方法是创建一个类,在它的析构函数上打印某个东西。你确定它先释放然后设置吗?ForEveR的答案表示它先设置然后释放。@7cows:ForEveR的顺序是正确的,但它不会改变最终结果。顺序唯一重要的情况是旧对象的析构函数抛出,这无论如何都是非常糟糕的做法。从概念上讲,它释放当前拥有的指针,并将值设置为传入的指针。我回答的重点并不是按什么顺序发生。你确定它先释放然后设置吗?ForEveR的答案表示它先设置然后释放。@7cows:ForEveR的顺序是正确的,但它不会改变最终结果。顺序唯一重要的情况是旧对象的析构函数抛出,这无论如何都是非常糟糕的做法。从概念上讲,它释放当前拥有的指针,并将值设置为传入的指针。我的回答并不是要说明事情发生的顺序。
foo_ptr.reset(foo_ptr.get());