Wednesday 8 August, 2007

Overloading "new"

In one of the previous article about operator new, we saw that it can always be overloaded.

operator new can be overloaded to define its own way of allocating memory for an object. User should be able to control the way how it allocates the memory for the object.

The global new operator is the one which invokes a call to appropriate version of operator new if its overloaded and then it will call the constructor to complete the object instantiation process.

Below is the pseudo code of what new operator does

new()
{

    // Call correct version of operator new() based on the parameters passed while initializing the object
    operator new(sizeof(CMyClass));

    // Call appropriate version of constructor
    CMyClass::CMyClass();    

}

Function operator new always has size_t as one of its parameter. The functionality of a default operator new will be as shown below,

void* operator new(size_t size)
{
    // allocate and return the pointer
    return malloc(size); 
}

Where it allocates size number of bytes and return the pointer which points to the allocated memory.

If user tries to instantiate an object of type CMyClass dynamically,

CMyClass *pObj = new CMyClass();

This will call the global new operator() function which will first call operator new(sizeof(CMyClass)) passing sizeof(CMyClass) as parameter to allocate required memory, then it will call the constructor CMyClass::CMyClass() to finish the object instantiation process.

In some cases user may want to allocate memory for an object in a predefined memory area. This can be achieved by overloading operator new().

void* operator new(size_t size, void *pMem)
{
    // just return the pre allocated memory pointer
    return pMem; 
}

User can invoke this by doing the following,

char *buf  = new char[500];                //pre-allocated buffer
CMyClass *pObj = new (buf) CMyClass();    //placement new

This will invoke the overloaded version of function operator new() which takes two parameters, first would be the size of the class and the next would be the pointer to pre-allocated buffer.

operator new(sizeof(CMyClass), buff);

And this overloaded version will just return the pointer to new operator() function which will then call the appropriate constructor.

This technic is popularly known as Placement New.

In the same way user should be able to overload operator new with different parameters.

Cheers!

2 comments:

Anonymous said...

How about exception handling inside operator new? Does it throw? what should be the exception specification in the function declaration?

Anonymous said...

This guide does not cover many important points. For example, you cannot placement new a class on a char buffer as the char buffer might not have the right alignment for the class. This can crash your program.