28

I was looking at the signature of new operator. Which is:

void* operator new (std::size_t size) throw (std::bad_alloc);

But when we use this operator, we never use a cast. i.e

 int *arr = new int;

So, how does C++ convert a pointer of type void* to int* in this case. Because, even malloc returns a void* and we need to explicitly use a cast.

templatetypedef
  • 328,018
  • 92
  • 813
  • 992
Chander Shivdasani
  • 9,259
  • 17
  • 71
  • 100

2 Answers2

44

There is a very subtle difference in C++ between operator new and the new operator. (Read that over again... the ordering is important!)

The function operator new is the C++ analog of C's malloc function. It's a raw memory allocator whose responsibility is solely to produce a block of memory on which to construct objects. It doesn't invoke any constructors, because that's not its job. Usually, you will not see operator new used directly in C++ code; it looks a bit weird. For example:

void* memory = operator new(137); // Allocate at least 137 bytes

The new operator is a keyword that is responsible for allocating memory for an object and invoking its constructor. This is what's encountered most commonly in C++ code. When you write

int* myInt = new int;

You are using the new operator to allocate a new integer. Internally, the new operator works roughly like this:

  1. Allocate memory to hold the requested object by using operator new.
  2. Invoke the object constructor, if any. If this throws an exception, free the above memory with operator delete, then propagate the exception.
  3. Return a pointer to the newly-constructed object.

Because the new operator and operator new are separate, it's possible to use the new keyword to construct objects without actually allocating any memory. For example, the famous placement new allows you to build an object at an arbitrary memory address in user-provided memory. For example:

T* memory = (T*) malloc(sizeof(T)); // Allocate a raw buffer
new (memory) T(); // Construct a new T in the buffer pointed at by 'memory.'

Overloading the new operator by defining a custom operator new function lets you use new in this way; you specify how the allocation occurs, and the C++ compiler will wire it into the new operator.

In case you're curious, the delete keyword works in a same way. There's a deallocation function called operator delete responsible for disposing of memory, and also a delete operator responsible for invoking object destructors and freeing memory. However, operator new and operator delete can be used outside of these contexts in place of C's malloc and free, for example.

templatetypedef
  • 328,018
  • 92
  • 813
  • 992
  • Step two should be "Invoke the object constructor, if any. If this throws *any exception*, free the above memory and propagate the exception." – GManNickG Feb 09 '11 at 06:23
  • @GMan- Thanks for spotting that! My bad. I'll fix it. – templatetypedef Feb 09 '11 at 06:24
  • Also, can u recommend me some books where i can find pearls like this? – Chander Shivdasani Feb 09 '11 at 06:33
  • @Chander Shivdasani- Glad to help; don't forget to accept the answer. ;-) This pearl of wisdom is based off of Scott Meyers' discussion of new in "Effective C++, 3rd Edition," which is widely considered one of the best books on C++. It will transform you from a good C++ coder to a GREAT C++ coder and expose you to all sorts of cool ideas that you never would have imagined could be expressed in C++. I highly recommend it. – templatetypedef Feb 09 '11 at 06:35
  • Thanks a lot...i will definitely get a copy of it. – Chander Shivdasani Feb 09 '11 at 06:37
5

You confuse new expression with operator new() function. When the former is compiled the compiler among other stuff generates a call to operator new() function and passes size enough to hold the type mentioned in the new expression and then a pointer of that type is returned.

sharptooth
  • 159,303
  • 82
  • 478
  • 911