Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
258 views
in Technique[技术] by (71.8m points)

c++ - Is it legal to call member functions after an object has been explicitly destroyed but before its memory was deallocated?

I have this code:

struct data {
  void doNothing() {}
};

int main() {
    data* ptr = new data();
    ptr->~data();
    ptr->doNothing();
    ::operator delete(ptr);
}

Note that doNothing() is being called after the object has been destroyed but before its memory was deallocated. It looks like "object lifetime" has ended however the pointer still points to proper allocated memory. The member function does not access any member variables.

Would member function call be legal in this case?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Yes, in the case of the code in the OP. Because the destructor is trivial, calling it doesn't end the object's lifetime. [basic.life]/p1:

The lifetime of an object of type T ends when:

  • if T is a class type with a non-trivial destructor (12.4), the destructor call starts, or
  • the storage which the object occupies is reused or released.

[class.dtor]/p5:

A destructor is trivial if it is not user-provided and if:

  • the destructor is not virtual,
  • all of the direct base classes of its class have trivial destructors, and
  • for all of the non-static data members of its class that are of class type (or array thereof), each such class has a trivial destructor.

No, not in the general case. Invoking a non-static member function after the object's lifetime has ended is UB. [basic.life]/p5:

[A]fter the lifetime of an object has ended and before the storage which the object occupied is reused or released, any pointer that refers to the storage location where the object will be or was located may be used but only in limited ways. For an object under construction or destruction, see 12.7. Otherwise, such a pointer refers to allocated storage (3.7.4.2), and using the pointer as if the pointer were of type void*, is well-defined. Indirection through such a pointer is permitted but the resulting lvalue may only be used in limited ways, as described below. The program has undefined behavior if:

  • [...]
  • the pointer is used to access a non-static data member or call a non-static member function of the object, or
  • [...]

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...