Big Problem! How to overload operator delete?

Started by
9 comments, last by iMalc 17 years, 8 months ago
Big Problem! How to overload operator delete? According to C++ standard, "A deallocation function can have more than one parameter."(see 3.7.3.2); however, I don't know how to use an overloaded delete operator. Let me use an example to illustrate this: /********************************************************/ #include <new> #include <iostream> using namespace std; void operator delete(void* p, const nothrow_t&) { cout << "Hello" << endl; } // (1) void operator delete(void* p, int a, int b) { cout << "World" << endl; } // (2) int main() { int* p = new(nothrow) int; delete p; // This cannot render to show 'Hello' or 'World' } /********************************************************/ Even if I use 'delete(nothrow, p);', it cannot render to show 'Hello' or 'World' either. My problem just lies here: Although I can write my own operator delete, I cannot use it. As far as I know, the C++ standard doesn't give an example to illustrate the usage of delete (The usage of new is given.). An ugly way to do this is to use function call: operator delete(nothrow, p); // This can render to show 'Hello' However, I don't think this is the answer to my question. Who know the correct one? Any help will be appreciatied. Thanks in advance.
God said: "Let there be light!" and there was light.
Advertisement
Overloaded versions of operator delete are only called if the constructor of class throws when the corresponding version of new is used. Otherwise only operator delete(void *) will be used.

This works:
void operator delete(void* p){    cerr << "World" << endl;}


May I ask why you need to overload the global operator delete? Looking for memory leaks?
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Quote:Original post by Fruny

This works:
void operator delete(void* p){    cerr << "World" << endl;}


May I ask why you need to overload the global operator delete? Looking for memory leaks?


Yes. I want to write a memory leak detector. So I need to overload the global delete operator with multiple parameters. Though your answer is correct, it is not what I want to know.
God said: "Let there be light!" and there was light.
Quote:Original post by SiCrane
Overloaded versions of operator delete are only called if the constructor of class throws when the corresponding version of new is used. Otherwise only operator delete(void *) will be used.


Would you please give me a further interpretation? A code example is the best. Thank you very much.
God said: "Let there be light!" and there was light.
Don't reinvent the wheel. This site has a free Memory Manager is which is exactly what you want. Source code is included, enjoy.

Edit: Typo.

"Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety." --Benjamin Franklin

Yes, use MMgr. I've used this for years and it has proven an indispensable tool.
Quote:Original post by Mike2343
Don't reinvent the wheel. This site has a free Memory Manager is which is exactly what you want. Source code is included, enjoy.

Edit: Typo.


I don't want to reinvent the wheel, I just want to explore the mechanism of how the wheel rolls.
God said: "Let there be light!" and there was light.
Quote:Original post by cqulyx
Quote:Original post by SiCrane
Overloaded versions of operator delete are only called if the constructor of class throws when the corresponding version of new is used. Otherwise only operator delete(void *) will be used.


Would you please give me a further interpretation? A code example is the best. Thank you very much.


#include <exception>#include <iostream>#include <new>void* operator new(size_t size, int a, int b){   std::cout << "new: " << a << ' ' << b << std::endl;   return ::operator new(size);}void operator delete(void* ptr, int a, int b){   std::cout << "delete: " << a << ' ' << b << std::endl;   ::operator delete(ptr);}class Foo{public:  Foo() { throw std::exception(); }};int main(){    try    {        Foo* f = new (23,42) Foo; // BOOM    }    catch(std::exception& e)    {        std::cout << "Caught exception." << std::endl;    }}


The memory allocation must be done before the constructor is executed. Since the constructor throws (directly, or because a base constructor or member constructor throws), the memory must somehow get released, otherwise you get a memory leak. This is done by calling the operator delete function that exactly matches the operator new that allocated the memory.

Foo's destructor itself is not run, since the constructor didn't complete, but whichever members have been fully constructed by the time the exception is thrown should get destroyed properly (IIRC).

Here, since the memory was allocated with the a version of new that take two extra int parameters, the compiler will generate a call to "the" version of delete that takes those two same int. Please note that if you do not provide the matching operator delete when you write an overload of operator new with custom parameters, this call is silently suppressed and you will get a memory leak.

Only the basic void operator delete(void*) will ever get called when you yourself do delete f;.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
To Fruny:

Thank you very very much for your instructive interpretation. I'm clear now.
God said: "Let there be light!" and there was light.

This topic is closed to new replies.

Advertisement