2

Hence the code below.

class A
{
    int x;
public:
    A() {x = 3;}
};


int main()
{
    void* mem = operator new(sizeof(A));
    A* obj = static_cast<A*>(new(mem)(A));
    std::cout << obj->x << std::endl;
    obj->A::~A();
    std::cout << obj->x << std::endl;
}

My first question is: Why I can directly call the destructor of A; My second question is: Why the output is:

3
3

The the object obj is not deleted after the destructor call? The second 3 bothers me.

cerkiewny
  • 2,761
  • 18
  • 36
Eduard Rostomyan
  • 7,050
  • 2
  • 37
  • 76
  • because it is normal function it is called automatically by compiler when the memory is being de allocated (object goes out of scope of main function). – cerkiewny May 11 '15 at 14:40

1 Answers1

8

Why can I call the destructor?

Because it is a public member function, and you can call public member functions.

Why is the object not deleted?

In your specific case, it still exists because A has a trivial destructor.

If it had a non-trivial one, it would be deleted in the sense that you are not allowed to use it anymore. If you do anyways, you have undefined behavior.

For a more detailed discussion on that read this.

Community
  • 1
  • 1
Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
  • Is it undefined behaviour ? I don't think so, it would be if you would delete the object not after you called the destructor... – cerkiewny May 11 '15 at 14:43
  • 2
    @cerkiewny Yes it absolutely is undefined behavior. `delete` calls the destructor and frees the memory. In this case, we're just doing the former explicitly without the latter. – Barry May 11 '15 at 14:45
  • @cerkiewny It is UB: "Once a destructor is invoked for an object, the object no longer exists" and neither does the member variable `x`. – Baum mit Augen May 11 '15 at 14:53
  • @BaummitAugen once it is invoked, not once you call it. As far as I understand it it is normal method, but so it happens the compiler automatically inputs its invocation when the object is deleted. If you are about to use object after this invocation the object does not exist therefore usage of it leads to undefined behaviour, but if you are calling the destructor directly the object still exists, so you can use it normally... – cerkiewny May 11 '15 at 15:02
  • @cerkiewny `obj->A::~A();` explicitly invokes the destructor. The destructor pretty much follows the normal member function syntax (see 12.4.13 in N3797 if you care about the formal wording). At the end of this expression, the object is dead. I am not quite sure what you are confused about. Maybe post a new question with are clear problem statement? – Baum mit Augen May 11 '15 at 15:11
  • @cerkiewny The memory the object lived in is still yours of course, if that is what you are talking about. You could construct a new object of type `A` in this memory and then use that. The original object definitely is unusable though. – Baum mit Augen May 11 '15 at 15:16
  • It is undefined behavior for the same reasons accessing uninitialized memory is always undefined behavior: http://stackoverflow.com/questions/11962457/why-is-using-an-uninitialized-variable-undefined-behavior-in-c – Sebastian May 11 '15 at 15:23
  • In short: Some architectures may reinitialize the value of x inside the dtor with a trap value. – Sebastian May 11 '15 at 15:24