牛骨文教育服务平台(让学习变的简单)
博文笔记

C++中小心谨慎的为数组分配空间

创建时间:2011-07-30 投稿人: 浏览次数:139

为自定义类型的数组分配空间得小心,陷阱很多。


首先,如下code是有问题的。

T* at = new T[1];

delete aT; //Error! using delete []

保持new[]和delete[]正确的成对使用很重要,因为数组的分配和归还所使用的函数不同于非数组;数组用operator new[]和operator delete[],而非数组使用operator new和operator delete来分配内存。


其次,从逻辑上说,只要声明了非数组形式的函数(op new和op delete),就应该为这些函数声明数组的形式。然而奇怪的是,在日常编程实践中,这一点往往被人所忽视。

如果是想调用全局的数组分配操作,那么,“仅仅转发对全局形式的调用”,可以让事情变得清晰。

class T{

public:

void* operator new (std::size_t size) ;

void* operator delete (void *) ;

void* operator new[] (std::size_t size)  {return ::operator new ( size) ;}

void* operator delete[] (void *p)   {return ::operator delete(p) ;}

};

如果不鼓励分配T数组,那么可以直截了当地把函数声明为private并且不提供定义。


另一个容易产生错误的地方在于,传递给op new[]的那个表示大小的参数值,取决于函数是如何被调用的。

如果直接调用op new或者op new[]时,这个大小正是分配的对象的大小。

aT = new T;

aT = static_cast<T*>(operator new (sizeof(T) ));

arrayT = static_cast<T*>(operator new[] (5*sizeof(T) ));

但是,隐式的调用op new[]时,编译器会略微增加一些内存请求。

arrayT = new T[5]; //请求内存量为 5*sizeof(T) + delta个byte

这里所请求的额外空间用来记录关于数组的一些信息(个数,单个元素的大小等),对以后回收内存是必不可少的。

不过,事情远远没有那么简单,这个额外空间对于不同数组分配而言,其大小也是会变化的。

如果你真的需要考虑这种情况,那么你必须避免编译器的干预,取而代之的是,使用普通的operate new

声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。