Why does the delete operator have two parameters?

I read about overloading new and deleted (and related topics, such as posting new / delete). The only thing that scares me so far is that the standard signature of the operator removes (in the-scope class):

void operator delete(void *rawMemory, std::size_t size) throw(); 

Delete is called like this:

 MyClass* ptr = new MyClass; delete ptr; 

So, like delete ptr; provide a second parameter for size? Also, can I assume that MyClass * is implicitly converted to void * in this case?

+8
c ++ memory
source share
3 answers

Short answer:

Operators

new and delete overloaded in the class area to optimize the distribution for objects of a particular class. But there may be special scenarios due to certain animals, such as Inheritance , which can lead to distribution requests larger than the class size itself. Since the most important task of overloading new and delete is a special setting for objects of size sizeof(Base) , nothing more or less, these overloaded operators must forward all other wrong sized memory requests to ::operator new and ::operator delete in order to be able to To do this, the size parameter must be passed as a parameter.

Long answer:

Consider a special scenario:

 class Base { public: static void * operator new(std::size_t size) throw(std::bad_alloc); }; class Derived: public Base { //Derived doesn't declare operator new }; int main() { // This calls Base::operator new! Derived *p = new Derived; return 0; } 

In the above example, due to inheritance, the Derived derived class inherits the new Base class statement. This makes the call statement new in the base class to allocate memory for the object of the derived class. The best way for a new operator to cope with this situation is to forward such calls requesting the "wrong" amount of memory for a standard new operator, for example:

 void * Base::operator new(std::size_t size) throw(std::bad_alloc) { if (size != sizeof(Base)) // if size is "wrong," ie != sizeof Base class { return ::operator new(size); // let std::new handle this request } else { //Our implementation } } 

When overloading the delete operator, you must also make sure that since the class operator for new requests sends the "wrong" size to ::operator new , one MUST send the "wrong size" requests to delete the operator: Since the original operators are guaranteed to process these requests in a standard way.

Thus, the user delete operator would be something like this:

 class Base { public: //Same as before static void * operator new(std::size_t size) throw(std::bad_alloc); //delete declaration static void operator delete(void *rawMemory, std::size_t size) throw(); void Base::operator delete(void *rawMemory, std::size_t size) throw() { if (rawMemory == 0) { return; // No-Op is null pointer } if (size != sizeof(Base)) { // if size is "wrong," ::operator delete(rawMemory); //delegate to std::delete return; } //If we reach here means we have correct sized pointer for deallocation //deallocate the memory pointed to by rawMemory; return; } }; 

Further reading:
The following C ++ entry - Faq talks about overloading the new and deleting in a standard way and may be well read for you:

How to write standard standard and remote iso C ++ statements?

+9
source share

So how to remove ptr; specify the second parameter for the size?

If the pointer type is a class type with a virtual destructor, from the dynamic information about the type of object. If it does not have a virtual destructor, and the type of the pointer corresponds to the type of the pointer - from the compile-time information about the type size. Otherwise, delete ptr works undefined.

+6
source share

This is the task of the compiler to remember the size that will be released when delete called. For delete ptr; it will pass sizeof(MyClass) , for delete[] ptr; he must remember the number of MyClass in the array and pass the correct size. I absolutely do not know how this strange corner of the tongue is. I can’t think of any other part of the language where the compiler should remember the runtime for you.

0
source share

All Articles