I'm new on StackOverflow and my first question is abot what happens to a running method, when I delete its object? Furthermore, what happens when I create a new object in the method, after I deleted the old one?
There's a small code snippet below to clarify my question. (Programming in C++11)
// Declaration and Definition of the class
class MyClass{
private:
static int counterFromClass = 0;
int counterFromObject;
public:
MyClass() {
counterFromObject = 0;
}
void ~MyClass() {}
void doSomething();
};
// Somewhere in the code a new object of the class is generated like this:
MyClass object = new MyClass();
// Then the method is called:
object->doSomething();
// Definition of the method
void MyClass::doSomething() {
this->counterFromObject++;
delete object;
MyClass object = new MyClass();
this->counterFromClass++;
}
If now the method doSomething()
is called:
object
or the new one? Both objects, the deleted and the new one, have the same name.So far what I have expirienced, it seems that the method will run to its end and execute all commands on its way, as long as they don't affect the deleted object. E.g. manipulating a static variable like counterFromClass
is allowed. And it seems also possible to manipulate data members of the object like counterFromObject
inside the method, as long as they are manipulated before the delete command.
Well, the code works but I know that it's not the best programming style. So I just started to work on a better solution, but I still got curious what exactly happens and if my thougths were correct. I would be grateful for answers.
If something's wrong with the question, please let me know because I am not that familiar with asking questions on StackOverflow yet.
Thank you :)
Lets take this function step by step:
void MyClass::doSomething() {
this->counterFromObject++;
This is perfectly legal. But you knew that.
delete object;
Again, perfectly legal. However, after that, it is your job to ensure that no code tries to access the object behind the object
pointer anymore. The problem is, that the this
pointer of the currently running method contains a copy of the dead objects address; the this
pointer is left dangling. Thus, dereferencing this
in any way, explicitly or implicitly, will immediately yield undefined behavior.
MyClass* object = new MyClass(); //I added the missing * to the type, we are not using java here.
This does not dereference this
, so it's perfectly ok. Note that this does not have any effect on the currently running method. The this
pointer is dangling, and there's no way of reassigning it.
this->counterFromClass++;
Formally, this is undefined behavior, as you are dereferencing this
. However, since counterFromClass
is static, it is likely that this won't crash your process, as the compiled code won't actually access the memory behind this
. Nevertheless, writing this->
means you have undefined behavior, so your process may crash anyway, or your compiler may simply throw this statement away! Whether it does so depends only on whether the compiler is smart enough to prove that you have undefined behavior here.
(As MartinBonner has found, the standard says in section 9.4 that the object expression is evaluated even when a static member is accessed via this->
, which means that the dangling this
pointer is actually dereferenced according to the standard. And dereferencing a dangling pointer is undefined behavior.)
So, it is mostly ok to delete an object while a method is running on it, and there are uses for this (one example is a reference counted object committing suicide when it's reference count drops to zero). However, if you ever need to do this,
write a warning comment that you may be deleting the this
object, and
make sure to return immediately afterwards.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With