Reputation: 2975
Consider below code:
#include <iostream>
#include <string>
using namespace std;
class A{
public:
int x;
public:
A(){x=0;}
void fun1(){
cout << "fun1 is called \n";
cout << "Address of this is " << this <<endl;
delete this;
}
void fun2()
{
cout << "fun2 called \n";
}
~A()
{
cout << "Object Destroyed" << endl;
}
};
int main()
{
A* ptr=new A;
cout << "Address of ptr is " << ptr <<endl;
ptr->fun1();
ptr->fun2();
return(0);
}
The Output is:
$ ./TestCPP
Address of ptr is 0x20010318
fun1 is called
Address of this is 0x20010318
Object Destroyed
fun2 called
My question is that when we call delete
in fun1()
it destroys the object pointed by this
pointer i.e at address 0x20010318
. It calls the destructor as shown by output. Hence after calling fun1()
the object at address 0x20010318
is destroyed and that memory is freed. Then why in the output we can see fun2()
? Is it just the garbage value ? I mean the object does not exist but at location pointed by ptr -> fun2()
the definition of fun2()
still exists?
Also can someone please explain how delete
works. For instance calling new
calls operator new
and the constructor
, is delete
operation similar?
Thanks
Upvotes: 0
Views: 175
Reputation: 131
The member function are resolved at compile time.
You can do something like:
A* ptr = NULL;
ptr->yourFunc();
It will work as long as you don't access the data store in the object (and its VTable, so you don't want to call method).
The 'this' will have a value of null, and it will be OK. But derefenrencing anything will result in a segfault.
Upvotes: 0
Reputation: 24850
When you are calling a non-virtual function from a class, the function
class A { public: void function(int k) { ... } };
will be written as something like
void __A_function(A* this, int k);
If your function does not involve with this
pointer, it will be called as a standard function, with this
parameter neglected.
Another thing I can predict is, even you do like this
class A
{
private:
int k;
public:
A() : k(10) {}
void function() { printf("%d\n",k); }
};
A* ptr=new A;
delete ptr;
ptr->function();
it will print out 10 in most cases. since the memory from new
is not yet cleaned up.
I will recommend Inside C++ Object Model for a detailed understanding of this.
Upvotes: 0
Reputation: 103713
What you are doing is technically undefined behavior, so really, anything can happen as far as the standard is concerned.
That aside, the actual behavior you are seeing can be easily reasoned about. fun2
is a non-virtual function. The compiler will resolve the call to it at compile time. When the object is destroyed, the function is not destroyed. And when you call ptr->fun2()
, your compiler just calls the function. Since the function doesn't rely on any member data, the output is quite predictable (even though, as far as the standard is concerned, it's not).
Here's a demonstration of me calling a non-virtual member function on a null pointer. Clearly this is wrong, and yet it prints statement exactly as expected: http://ideone.com/pddnGt
This is not to say the code is not bad. You should never have undefined behavior in your code. On lower optimization levels, for debugging purposes, a compiler may very well throw in checks for this kind of thing and halt the program with an error message, or throw an exception.
Upvotes: 4
Reputation: 6511
When you call delete
, the Operating System is informed that this memory no longer needed, and therefore available for future allocation. However, it will not be automatically wiped.
In your case, that memory is not used by anyone else before your call to fun2
. No one tried to allocate any memory in the heap in between the two function calls. Therefore, the object is still there and never tampered. However, it doesn't mean memory allocation is impossible in between the two calls (for example an interrupt may be triggered and memory may be allocated during processing of the interrupt). Therefore, you should never do this. :)
Upvotes: 0
Reputation: 731
If your method isn't virtual and doesn't contain a reference to a member, it can works with some compilers as the method in assembly doesn't need a valid this pointer. Anyway, you must be carrefull with undefined behaviours.
Upvotes: 1
Reputation: 171303
Is it just the garbage value ? I mean the object does not exist but at location pointed by
ptr -> fun2()
the definition offun2()
still exists?
Yes, it's undefined behaviour, but because nothing has actually re-used the memory it seems to "work" OK. It's actually a serious bug though. (N.B. The definition of A::fun2()
never goes anywhere, that is code, not data, so exists for the entire lifetime of the program, the object at the memory location ptr
stops existing, but the definition of its member functions doesn't.)
For instance calling
new
callsoperator new
and the constructor , isdelete
operation similar?
Yes, it calls the destructor to destroy the object at that location then invokes operator delete
to free the memory.
Upvotes: 2
Reputation: 96241
After the delete
is called in fun1
your call to fun2
is illegal. C++ doesn't hold your hands so for this "undefined behavior" anything is allowed to happen, including properly called fun2
.
In fact delete
calls the object's destructor and then frees the memory, just the opposite of new
.
Upvotes: 0