C++ – Why ::operator new[] is Necessary When ::operator new is Enough

c++memory-managementnew-operatoroverloadingstandards

As we know, the C++ standard defines two forms of global allocation functions:

void* operator new(size_t);
void* operator new[](size_t);

And also, the draft C++ standard (18.6.1.2 n3797) says:

227) It is not the direct responsibility of operator
new or operator delete to note the repetition
count or element size of the array. Those operations are performed
elsewhere in the array new and delete expressions. The array new
expression, may, however, increase the size argument to operator
new to obtain space to store supplemental information.

What makes me confused is:

What if we remove void* operator new[](size_t); from the standard, and just use void* operator new(size_t) instead? What's the rationale to define a redundant global allocation function?

Best Answer

I think ::operator new[] may have been useful for fairly specialized systems where "big but few" arrays might be allocated by a different allocator than "small but numerous" objects. However, it's currently something of a relic.

operator new can reasonably expect that an object will be constructed at the exact address returned, but operator new[] cannot. The first bytes of the allocation block might be used for a size "cookie", the array might be sparsely initialized, etc. The distinction becomes more meaningful for member operator new, which may be specialized for its particular class.

In any case, ::operator new[] cannot be very essential, because std::vector (via std::allocator), which is currently the most popular way to obtain dynamic arrays, ignores it.

In modern C++, custom allocators are generally a better choice than customized operator new. Actually, new expressions should be avoided entirely in favor of container (or smart-pointer, etc) classes, which provide more exception safety.