In C ++, the matching between arrays and non-array operators must be maintained during memory allocation and return:
T * aT = new T; // non-array
T * arrT = new T [16]; // Array
Delete aT; // non-array
Delete [] arrT; // Array
AT = new T [1]; // Array
Delete aT; // error! Operators in array form should be used
It is important to keep these functions correctly used in pairs, because the functions used for Array allocation and return are different from those in non-array form. For arrays, the new expression does not use operator new to allocate storage areas for arrays, but uses array new. Similarly, the delete expression does not call operator delete to release the array Storage zone, but calls array delete. More specifically, when assigning an array, we should use a different operator, namely new [], instead of using the new operator like allocating a non-array object. Memory planning is similar.
Array new and array delete are the counterparts of operator new and operator delete arrays. Their declaration methods are similar:
Void * operator new (size_t) throw (bad_alloc); // operator new
Void * operator new [] (size_t) throw (bad_alloc); // array new
Void operator delete (void *) throw (bad_alloc); // operator delete
Void operator delete [] (void *) throw (bad_alloc); // array delete
The most common confusion about the array form of these functions occurs when a specific class or class hierarchy uses the operator new and operator delete members to define their own memory management methods:
Class Handle
{
Public:
//...
Void * operator new (size_t );
Void operator delete (void *);
//...
};
The Handle class defines non-array memory management functions, but they are not used in the case of Handle arrays. In the case of arrays, Global array new and array delete are called:
Handle * arrHandle = new Handle [MAX]; // call: operator new []
//...
Delete [] arrHandle; // call: operator delete []
Logically, as long as non-array functions (operator new and operator delete) are declared, arrays should be declared for these functions. In daily programming practices, this is often ignored. If you want to call the Global Array allocation operation, you can define the local form of "forwarding requests to the global form only" to make things clearer:
Class Handle
{
Public:
//...
Void * operator new (size_t );
Void operator delete (void *);
Void * operator new [] (size_t n)
{
Return: operator new (n );
}
Void operator delete [] (void * p)
{
: Operator delete (p );
}
//...
};
If the purpose is to prohibit the allocation of Handle arrays, you can declare functions in the array form as private and do not provide definitions.
Another cause of confusion and errors is that the parameter value that is passed to array new indicates the size, depending on how the function is called. When operator new is implicitly called in a new expression, the compiler determines the memory size required and passes this quantity as a parameter to operator new. The quantity is the size of the objects being allocated:
AT = new T; // call operator new (sizeof (T ());
You can also call operator new directly. In this case, you must specify the number of bytes to be allocated:
AT = static_cast <T *> (operator new (sizeof (T )));
You can also directly call array new:
ArrT = static_cast <T *> (operator new [] (sizeof (T) * 16 ));
However, when array new is implicitly called using the new expression, the compiler often adds some memory requests slightly:
ArrT = new T [16]; // The request memory is * sizeof (T) + delta bytes.
The requested extra space is generally recorded by the runtime memory manager (runtime memory manager) about the Array (including the number of allocated elements and the size of each element) it is essential to reclaim Memory later. However, this is far from the case. The Compiler may not request additional memory space for each array allocation, and the size of the memory space requested for additional requests may also change for different array allocation.
The difference in the number of request memory is usually considered only when writing very low-level code. In this case, the storage area of the array is directly processed. If you plan to write the underlying code, the simplest practice is to avoid directly calling array new and related interventions executed by the compiler. Instead, you can use the common operator new.