Reputation: 861
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 :)
Upvotes: 7
Views: 2892
Reputation: 40665
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.
Upvotes: 6
Reputation: 11020
Technically speaking, this is undefined behavior. What happens in practice, however, is that most compiler implementations will store method instructions in the same place in memory, regardless of whether the methods are static or not, just like static member variables for a class are stored in the same place in memory. This is because method logic does not vary from instance to instance. What is stored in different memory from instance to instance is non-static member variables.
Additionally, when compiled an implicit parameter is added to the functions, which is a pointer to an instance of the class. And this is how the compiled function gets access to the member variables, through the implicit "this" pointer.
Therefore, when you delete the object in the middle of executing the function, it will continue executing until it attempts to use a non-static member variable, which was stored in memory allocated specifically for that object, that was now deallocated. At this point it may continue executing if the memory has not been reclaimed, or if you're lucky the program will crash.
Upvotes: 0
Reputation: 1449
Code and allocated space for an object are stored separately. Code is only stored once in your binary (and loaded in memory when executing the binary). Objects are created dynamically in memory, on the heap or the stack. The code of a method operates on the object's data using the this
pointer (which is an 'invisible' argument to a method, and can be accessed by explicitly writing this
in the method, or is used implicitly when accessing members).
Nothing will happen to the running function if you delete the object. It will continue running and execute commands. The this
pointer will not change during execution (because, as already mentioned, it's like an argument to the function copied by value). However, if the object is deleted, it will most likely not point to anything useful. So:
this
pointer will either give you a SEGFAULT because you access memory that doesn't belong to the application anymoreSo to answer your questions:
this
. Your second new is not guaranteed to give you the same pointer value (memory address).Upvotes: 1
Reputation: 180245
Deleting the object invalidates the this pointer. Creating a new object a probably (but not 100%) gives you a new pointer. But in the code above, the this pointer does not magically change to the new object. You have Undefined Behaviour.
Upvotes: 0