What actually happen when I execute this code?
class MyClass
{
MyClass()
{
//do something
delete this;
}
}
What actually happen when I execute this code?
class MyClass
{
MyClass()
{
//do something
delete this;
}
}
Note: This answer applies to C++03, and it seems like the behavior was changed in C++11 and higher so that this is now undefined behavior.
It turns out that in this particular case the code is legal, but you're ε-away from undefined behavior.
The C++03 standard defines the notion of the "lifetime" of an object to be the time between which its constructor has finished running and when the destructor starts running. It also explicitly states (in §3.8/5) that
Before the lifetime of an object has started [...] If the object will be or was of a class type with a non-trivial destructor, and the pointer is used as the operand of a delete-expression, the program has undefined behavior.
Since an object's lifetime has not started until the constructor finishes, inside the constructor the this
pointer you've referred to has not begun its lifetime, trying to delete
it in this case is totally safe. However, if you write a destructor for the class, then you'll immediately run into undefined behavior here.
In addition, if you change the constructor so that you try referencing any of the class's data members after you delete the object, you'll get undefined behavior. If the object was allocated on the stack, you'll get undefined behavior. If the object was static, you'll get undefined behavior. If the object was allocated using new
, then the pointer the client will get back to it will be invalid and using it will result in undefined behavior. In general, don't try doing this!
malloc(sizeof(T))
to a T*
to get such a pointer. The issue is more that because the object hasn't started its lifetime yet, the behavior of destructing it is undefined. –
Room new
will use an invalid pointer value (by copying it to something, if only the temporary value that is the result of the new expression). Using a deleted pointer value is UB in the standard, although it doesn't cause anything bad to happen on any implementation I know. –
Miff CallFunction(MyClass())
will cause undefined behavior since the temporary MyClass
is not allocated via new
. However, writing something like CallFunction(new MyClass)
is safe as long as you don't try to use the parameter! –
Room The first thing that I want to understand here is WHY do you want to do something like this?
Constructor is a member function where your object is actually getting constructed and you can delele an object once it is fully constructed, that's why doing somrthing like this -
class A
{
public:
A()
{
delete this;
}
~A()
{
}
};
results in an undefined behavior.
Also, to add to this, if you perform delete this
in the destructor, it is also not correct since the object is itself undergoing the destruction and doing delete this
in the destructor will again call the destructor.
class A
{
public:
A()
{
}
~A()
{
delete this; // calls the destructor again.
}
};
Assuming your object is never inherited by anything this should work fine. Your constructor runs and then the destructor is immediately called. If anything inherits this object it will break since this constructor will be called before the inheriting constructor.
delete
) inside the constructor cause UB? –
Hove © 2022 - 2024 — McMap. All rights reserved.
delete this
) and the NULL pointer returned from the ctor. Of course, a better way to do this is use a factory method to accomplish this (factory checks if there is enough memory, and only if there is enough memory, proceeds with construction). – Unifoliatedelete this
. (Are you confusing constructor with call to "new"?) – Ornerystop_requested() == true
when constructing, the wrapper callback function is called right in the stop_callback constructer, deleting the stop_callback object itself. – Maxi