Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does dynamic_cast work inside overloaded operator delete?

I came across this:

struct Base {
  void* operator new (size_t);
  void operator delete (void*);
  virtual ~Base () {}  // <--- polymorphic
};
struct Derived : Base {};

void Base::operator delete (void *p)
{
  Base *pB = static_cast<Base*>(p);
  if(dynamic_cast<Derived*>(pB) != 0)
  { /* ... NOT reaching here ? ... */ }
  free(p);
}

Now if we do,

Base *p = new Derived;
delete p;

Surprisingly, the condition inside the Base::delete is not satisfied Am I doing anything wrong ? Or casting from void* looses the information of Derived* ?

like image 545
iammilind Avatar asked Jun 22 '11 05:06

iammilind


People also ask

Can delete operator be overloaded?

New and Delete operators can be overloaded globally or they can be overloaded for specific classes. If these operators are overloaded using member function for a class, it means that these operators are overloaded only for that specific class.

What is the use of dynamic_cast?

The dynamic_cast operator ensures that if you convert a pointer to class A to a pointer to class B , the object of type A pointed to by the former belongs to an object of type B or a class derived from B as a base class subobject.

What does dynamic_cast return in C++?

If the cast is successful, dynamic_cast returns a value of type new-type. If the cast fails and new-type is a pointer type, it returns a null pointer of that type. If the cast fails and new-type is a reference type, it throws an exception that matches a handler of type std::bad_cast.

What is the behavior of dynamic_cast when Downcasting is detected on references?

So when dynamic_cast for a pointer type fails it returns a null pointer and the caller can check for that, but when it fails for a reference type it can't return a null reference, so an exception is the only reasonable way to signal a problem. Save this answer.


1 Answers

Function operator delete is a raw-memory deallocation function. It is invoked when the actual object (that used to reside in that memory) has already been destructed. I.e. by the time you get into operator delete you object has already been wiped out. The memory the pointer points to is essentially "raw", it no longer contains an object. Trying to use any polymorphic functionality on this raw memory is useless - it will not work.

In more formal terms, according to the language standard the lifetime of an object with non-trivial destructor ends once its destructor starts. In your case all destructors have already done their work. The lifetime of the object is already over, while dynamic_cast requires a "live" object.

P.S. Formally, it is permissible to use dynamic_cast in a destructor as long as some conditions are met (see 12.7/5), but when all destructors are finished (as in your case), dynamic_cast is no longer usable.

like image 84
AnT Avatar answered Sep 28 '22 07:09

AnT