This blog is subject the DISCLAIMER below.

Tuesday, February 06, 2007

Advanced C++ part 6 : Advanced Memory Management part 3 : overriding new and delete, and why you would need that

You can override new and delete for a certain class. So your operators will be called only if that class (or its derived classes) is being dynamically allocated. You can also override the global new and delete so your operators will be called on any dynamic allocation that occurs in your program.

Question:

Why would I need to override new and delete?


Answer:
For global or class-based:
In case you want to implement your garbage collector, or whatever application that needs to keep track of memory allocations (profiler, reference counter, etc.)

For class based:
For some classes you might need to allocate them on a certain memory location (like video memory or a shared memory area, I don't know if you might need that on a memory-mapped file or not.)

Question:

How to override it then?

Answer:

This is just example code to show you how you can do it, not how you should do it.

Global

void* operator new (size_t size)
{
void* allocated_mem = malloc(size);
if (!allocated_mem)
throw std::bad_alloc(); // if failed to allocate, throw bad_alloc exception
return allocated_mem;
}
void operator delete (void *pointer)
{
free(pointer);
}

Class-based

Definition
static void* operator new (size_t size);
static void operator delete (void* p);
Implementation

void* Class1::operator new (size_t size)
{
void* allocated_mem = malloc(size);
return allocated_mem;
} // At this point, Class1 default constructor get called (automatically)


// At this point Class1 destructor gets called (automatically)
void Class1::operator delete (void* pointer)
{
free(p);
} // At this point Class1 destructor gets called (automatically)

Next article isA will take about placement new.

Further reading:
http://www.informit.com/guides/content.asp?g=cplusplus&seqNum=40&rl=1

2 comments:

Hossameldin said...

Thanks Mohamed for the post.
I just have a little correction:

You mentioned that the destructor will be called after calling delete().
The correct sequence should be that delete() will be called after calling the class's destructor, not before that.

Mohammad Nabil said...

Thanks for correction. It was my mistake I didn't read the full sentence from the reference site I put in the article.
And sorry for the wrong information, I will edit the article now.

[Quote]
void A::operator delete (void *p)
{
release(p); // return memory to pool
} // A's dtor implicitly called at this point

C++ guarantees that an object's destructor is automatically called just before delete executes.
[/Quote]