Item 37. Array Allocation
分配内存时用new,则释放时用delete; 分配时用new[],则释放时用delete[]。
T *aT = new T; // non-array
T *aryT = new T[12]; // array
delete [] aryT; // array
delete aT; // non-array
----------------------------------------------------
1、why?为什么需要成对使用?
分配数组和非数组时,使用的操作符不一样,对应的释放操作也不一样。
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(); // operator delete
void operator delete[]( void * ) throw(); // array delete
2、当一个类只写了new和delete时,对该类进行数组分配时,调要的分配和释放操作函数是两个那个全局的::operator new[] 和::operator delete[]。
因此为了确保分配行为的一致,同时声明数组和非数组的分配释放操作是个不错的选择。
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 ); }
//...
};
3、参数size_t是如何传入的?
隐式调用operator new时,编译器作了手脚:
aT = new T; // calls operator new( sizeof(T) );
而我们也可以直接调用operator new :
aT = static_cast<T *>(operator new( sizeof(T) ));
对于数组:
aryT = static_cast<T *>(operator new[]( 5*sizeof(T) ));
4、隐式调用operator new[],发生了什么?
隐式调用operator new[]时,编译器通常多分配了一点内存+delta :
aryT = new T[5]; // request 5*sizeof(T) + delta bytes
5、额外内存的用途:
用来运行时内存的管理,它记录了释放内存时需要的数组信息(分配元素的数目,每个元素的大小等)。