Possible Duplicate:
Why is the below piece of code is not crashing, though I have deleted the object?
Today, I found out that I know nothing about C++ memory management. Please take a look at this piece of code:
class A
{
public:
A(){std::cout << "constructor called" << this << std::endl;}
~A(){std::cout << "destructor called" << this << std::endl;}
void test (){std::cout << "test" << this << std::endl;}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
A *aa = new A();
delete aa;
aa->test();
aa->test();
aa->test();
std::cout << "still works\n";
return a.exec();
}
Why doesn't it crash? Why does it still continue executing, despite the destructor was called? When I call the test
method, I deal with memory that doesn't belong to the application any more.
What is more surprising is it still works even if I insert aa = NULL;
right after delete aa;
. The test
method gets called all right. I need to confess that I'm totally confused. What is the purpose of destructors and assigning NULL if it doesn't have any effect?
There are two ways to answer your question:
Your code has an undefined behavior (UB).
It dereferences a NULL
or a delete
ed pointer. As per the C++ standard both invoke undefined behavior. Whether it works or not is pointless.
Undefined behavior means that any behavior is possible, and it may or may not crash, but it means that your program cannot be expected to give any well-defined output. It simply means that any behavior is possible and it may not be consistent or well defined.
It doesn't crash because the compiler does not actually dereference this
while calling member function. Unless the function is an virtual
function, the compiler converts the member function call to a usual function call by passing this
as the first parameter to the function. It can do so, because the compiler can exactly determine which function to call at compile time itself. So practically, calling the member function through deleted or NULL
pointer does not dereference the this
(which is invalid if its NULL
or delete
ed). Further, the this
is dereferenced only if any member is accessed inside the function body.
In your case, you never access any member inside the function body and hence it does not crash. Add a member and dereference it inside your function and it should definitely crash.
Regardless of what is said in a practical answer, the technical answer is above and over everything since the standard says that.