move-construct object with placement new

我的未来我决定 提交于 2019-12-12 19:45:25

问题


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
}

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)

Thus, when exiting the scope of bar(), f1's destructor will try to delete an invalid (uninitialized) pointer.


回答1:


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));
}

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_);
}

will fix the bug.



来源:https://stackoverflow.com/questions/38171964/move-construct-object-with-placement-new

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!