Calling non-static member function outside of object's lifetime in C++17

前端 未结 5 1661
无人及你
无人及你 2021-02-03 22:06

Does the following program have undefined behavior in C++17 and later?

struct A {
    void f(int) { /* Assume there is no access to *this here */ }
};

int main(         


        
5条回答
  •  星月不相逢
    2021-02-03 22:38

    In addition to what others said:

    a->~A(); delete a;

    This program has a memory leak which itself is technically not undefined behavior. However, if you called delete a; to prevent it - that should have been undefined behavior because delete would call a->~A() second time [Section 12.4/14].

    a->~A()

    Otherwise in reality this is as others suggested - compiler generates machine code along the lines of A* a = malloc(sizeof(A)); a->A(); a->~A(); a->f(0);. Since no member variables or virtuals all three member functions are empty ({return;}) and do nothing. Pointer a even still points to valid memory. It will run but debugger may complain of memory leak.

    However, using any nonstatic member variables inside f() could have been undefined behavior because you are accessing them after they are (implicitly) destroyed by compiler-generated ~A(). That would likely result in a runtime error if it was something like std::string or std::vector.

    delete a

    If you replaced a->~A() with expression that invoked delete a; instead then I believe this would have been undefined behavior because pointer a is no longer valid at that point.

    Despite that, the code should still run without errors because function f() is empty. If it accessed any member variables it may have crashed or led to random results because the memory for a is deallocated.

    new(a) A

    auto a = new A; new(a) A; is itself undefined behavior because you are calling A() a second time for the same memory.

    In that case calling f() by itself would be valid because a exists but constructing a twice is UB.

    It will run fine if A does not contain any objects with constructors allocating memory and such. Otherwise it could lead to memory leaks, etc, but f() would access the "second" copy of them just fine.

提交回复
热议问题