【发布时间】:2016-11-05 10:23:44
【问题描述】:
通过placement new来移动构造对象不是UB吗?
假设我有这个代码:
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_ 在通过放置 new 和 move 构造构造第二个 foo 后将有一个未定义的值(这个未定义的值来自未初始化的 Foo f2 的 foo_ 在其移动构造函数中,因为这些值是 交换了)
因此,当退出 bar() 的作用域时,f1 的析构函数会尝试删除一个无效(未初始化)的指针。
【问题讨论】:
-
放置或其他
new获取内存。构造函数将内存转换为对象。new不在乎你对内存做了什么。构造函数并不关心你如何获得内存。是的,这种行为是未定义的,但它与您分配有问题的对象的方式无关。可以是自动的或任何其他类型的。
标签: c++ c++11 placement-new move-constructor