Jump to content
  • Advertisement
Sign in to follow this  
cqulyx

Big Problem! How to overload operator delete?

This topic is 4424 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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;.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!