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?
The new operator invokes the function operator new . For arrays of any type, and for objects that aren't class , struct , or union types, a global function, ::operator new , is called to allocate storage. Class-type objects can define their own operator new static member function on a per-class basis.
The new operator is used to initialize the memory and return its address to the pointer variable ptr1 and ptr2. Then the values stored at memory positions pointed to by ptr1 and ptr2 are displayed. Finally the delete operator is used to free the memory.
New and Delete operators can be overloaded globally or they can be overloaded for specific classes.
Operator vs function: new is an operator as well as a keyword whereas operator new is only a function.
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.
::operator new[]
and ~delete[]
facilitate memory usage debugging, being a central point to audit allocation and deallocation operations; you can then ensure the array form is used for both or neither.
There are also lots of plausible if highly unusual/crude tuning uses:
allocate arrays from a separate pool, perhaps because that crucially improved average cache hits for small single-object dynamically-allocated objects,
different memory access hints (ala madvise
) for array/non-array data
All that's a bit weird and outside the day-to-day concerns of 99.999% of programmers, but why prevent it being possible?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With