new有三种使用方式:plain new、nothrow new、placement new.

1.plain new/delete.普通的new,定义如下:

void *operator new(std::size_t) throw(std::bad_alloc);

void operator delete(void*) throw();

注:标准C++ plain new失败后抛出标准异常std::bad_alloc而非返回NULL,因此检查返回值是否为NULL判断分配是否成功是徒劳的。

测试程序:

Code Snippet
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. char* GetMemory(unsigned long size)
  5. {
  6.     char* p = new char[size];//分配失败,不是返回NULL
  7.     return p;
  8. }
  9.  
  10. int main()
  11. {
  12.     try
  13.     {
  14.         char* p = GetMemory(10e11);//分配失败抛出异常std::bad_alloc
  15.         if (!p)//徒劳
  16.             cout << "failure" << endl;
  17.         delete [] p;
  18.     }
  19.     catch (const std::bad_alloc & ex)
  20.     {
  21.         cout << ex.what() << endl;
  22.     }
  23.  
  24.     return 0;
  25. }

输出:

std::bad_alloc
2.

nothrow new/delete不抛出异常的运算符new的形式,new失败时返回NULL。

定义如下:

void *operator new(std::size_t,const std::nothrow_t&) throw();

void operator delete(void*) throw();

struct nothrow_t{};  const nothrow_t nothrow;//nothrow作为new的标志性哑元

测试程序:

Code Snippet
  1. #include <iostream>
  2. #include <new>
  3. using namespace std;
  4.  
  5. char* GetMemory(unsigned long size)
  6. {
  7.     char* p = new(nothrow) char[size];//分配失败,返回NULL
  8.     if (NULL == p)
  9.         cout << "alloc failure!" << endl;
  10.  
  11.     return p;
  12. }
  13.  
  14. int main()
  15. {
  16.     try
  17.     {
  18.         char* p = GetMemory(10e11);
  19.         if (p == NULL)
  20.             cout << "failure" << endl;
  21.         delete [] p;
  22.     }
  23.     catch (const std::bad_alloc & ex)
  24.     {
  25.         cout << ex.what() << endl;
  26.     }
  27.  
  28.     return 0;
  29. }

输出:

alloc failure!
failure
3.

placement new/delete 主要用途是:反复使用一块较大的动态分配成功的内存来构造不同类型的对象或者它们的数组。例如可以先申请一个足够大的字符数组,然后当需要时在它上面构造不同类型的对象或数组。placement new不用担心内存分配失败,因为它根本不分配内存,它只是调用对象的构造函数。

测试程序:

Code Snippet
  1. #include <iostream>
  2. #include <new>
  3. using namespace std;
  4.  
  5. class ADT
  6. {
  7. public:
  8.     ADT() { cout << "ADT::ADT" << endl; }
  9.     ~ADT() { cout << "ADT::~ADT" << endl; }
  10.     int i;
  11.     int j;
  12. };
  13.  
  14. int main()
  15. {
  16.     char* p = new(nothrow) char[sizeof(ADT)+2];
  17.     if (p == NULL)
  18.         cout << "failure" << endl;
  19.  
  20.     ADT* q = new(p) ADT;//placement new:不必担心失败
  21.     //delete q;//错误!不能在此处调用delte q;
  22.     q->ADT::~ADT();//显示调用细够函数
  23.     delete []p;
  24.     return 0;
  25. }

输出:

ADT::ADT
ADT::~ADT

参考资料:

http://blog.sina.com.cn/s/blog_446b43c10100d7ci.html