Dynamic memory is allocated using operator new. new is followed by a data type specifier and, if a sequence of more than one element is required, the number of these within brackets []. It returns a pointer to the beginning of the new block of memory allocated. Its syntax is:

pointer = new type
pointer = new type [number_of_elements]

An expression with the new operator, first calls function operator new (i.e., this function) with the size of its type specifier as first argument, and if this is successful, it then automatically initializes or constructs the object (if needed). Finally, the expression evaluates as a pointer to the appropriate type.

// Allocates size bytes of storage, suitably aligned to represent any object of that size, and returns a non-null 
// pointer to the first byte of this block. On failure, it throws a bad_alloc exception. 
void* operator new (std::size_t size) throw (std::bad_alloc);

// Same as above, except that on failure it returns a null pointer instead of throwing an exception.
// If replaced, both the first and second versions shall return pointers with identical properties.
void* operator new (std::size_t size, const std::nothrow_t& nothrow_value) throw();

// Returns ptr (no storage is allocated). Notice though that, if the function is called by a new-expression,
// the proper initialization will be performed (for class objects, this includes calling its default constructor).
void* operator new (std::size_t size, void* ptr) throw();

Above, ‘size’ is Size in bytes of the requested memory block. This is the size of the type specifier in the new-expression when called automatically by such an expression. If this argument is zero, the function still returns a distinct non-null pointer on success (although dereferencing this pointer leads to undefined behavior).

Example:

class MyClass {
  int data[100];
  MyClass() {std::cout << "constructed [" << this << "]\n";}

  void * MyClass::operator new(size_t size)
  {
      void *ptr = ExAllocatePoolWithTag(NonPagedPool, size, MyClass_POOL_TAG);
      memset(ptr, 0, size);

      return ptr;
  }

  void MyClass::operator delete(void *ptr)
  {
      ExFreePoolWithTag(ptr, MyClass_POOL_TAG);
  }
};

int main () {

  // Allocates memory by calling: operator new (sizeof(MyClass))
  MyClass * p1 = new MyClass;

  // Allocates memory by calling: operator new (sizeof(MyClass),std::nothrow)
  MyClass * p2 = new (std::nothrow) MyClass;

  // Does not allocate memory -- calls: operator new (sizeof(MyClass),p2)
  // but constructs an object at p2
  new (p2) MyClass;

  // Allocates memory by calling: operator new (sizeof(MyClass))
  // but does not call MyClass's constructor
  MyClass * p3 = (MyClass*) ::operator new (sizeof(MyClass));

  return 0;
}