移动 - 构造对象与放置新 [英] move-construct object with placement new
问题描述
是不是UB通过placement new来移动构造对象?
Is it not UB to move-construct an object via placement new?
让我们说我有这个代码:
Let's say I have this code:
class Foo {
public:
Foo() { foo_ = new int; }
~Foo() { delete foo_; }
Foo(Foo &&f) {
foo_ = std::swap(f.foo_, foo_);
}
private:
int* foo_;
}
void bar() {
void* pMem = malloc(sizeof(Foo));
Foo f1;
// move-construct with placement new:
new((Foo*)pMem) Foo(std::move(f1)); // f2 in *pMem
// now f1 will contain a pointer foo_ of undefined value
// when exiting scope f1.~Foo(){} will exhibit UB trying to delete it
}
如果不明显,f1的成员foo_在构造完成后会有一个未定义的值(这个未定义的值来自于其移动构造函数内的未初始化的Foo f2的foo_,因为值是交换的)
If it's not obvious, f1's member foo_ will have an undefined value after constructing the second foo by placement new and move construction (this undefined value comes from the uninitialized Foo f2's foo_ inside its move-constructor because the values are swapped)
因此,当退出bar()的范围时,f1的析构函数会尝试删除一个无效的(未初始化的)指针。
Thus, when exiting the scope of bar(), f1's destructor will try to delete an invalid (uninitialized) pointer.
推荐答案
>这与展示位置新功能无关。这个代码会有同样的问题:
This has nothing to do with placement new. This code would have the exact same problem:
void bar() {
Foo f1;
Foo f2(std::move(f1));
}
每个构造的对象最终都会被破坏,无论是否使用placement-new,移动构造函数都会将移动对象置于无效状态。从对象移动并不意味着它不会被破坏。它会。
Every constructed object will get destructed eventually, so it doesn't matter if you use placement-new or not, your move-constructor messes up by leaving the moved-from object in a invalid state. Moving from an object doesn't mean it won't get destructed. It will. You have to let a valid object behind when you move from it.
Foo(Foo &&f) : foo_(nullptr) {
std::swap(f.foo_, foo_);
}
将修复此错误。
这篇关于移动 - 构造对象与放置新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!