Bog*_*tza 2 c++ placement-new move-constructor c++11
是不是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
}
Run Code Online (Sandbox Code Playgroud)
如果不明显,f1的成员foo_将在构造第二个foo后通过放置new和move构造得到一个未定义的值(这个未定义的值来自未初始化的Foo f2在其move-constructor中的foo_,因为值是交换的)
因此,当退出bar()的范围时,f1的析构函数将尝试删除无效(未初始化)指针.
这与放置新内容无关.这段代码会有完全相同的问题:
void bar() {
Foo f1;
Foo f2(std::move(f1));
}
Run Code Online (Sandbox Code Playgroud)
每个构造的对象最终都会被破坏,所以无论你是否使用placement-new都没关系,你的move-constructor会让被移动的对象处于无效状态而混乱.从物体移动并不意味着它不会被破坏.它会.当你离开它时,你必须让一个有效的对象落后.
Foo(Foo &&f) : foo_(nullptr) {
std::swap(f.foo_, foo_);
}
Run Code Online (Sandbox Code Playgroud)
将修复该错误.
| 归档时间: |
|
| 查看次数: |
1239 次 |
| 最近记录: |