轉自:http://badboywang.iteye.com/blog/446350
1. plain new 普通new
void*operator new(std::size_t)throw(std::bad_alloc); void operator delete( void *) throw();
該運算子在分配失敗時將拋出異常,而非返回NULL。使用時要包含 <new>標頭檔。正常使用new,但要配以異常處理。如:
char *getMemory(unsigned long size) { char * p = new char[size]; return p; } void main(void ) { try{ char * p = getMemory(1000000);//可能發生異常 // ... delete [ ] p; } catch(const std::bad_alloc & ex) { cout < <ex.what(); } }
2.nothrow new 不拋擲異常new
void*operator new(std::size_t,const std::nothrow_t & )throw(); void operator delete( void *) throw();
該運算子在分配失敗時不拋出異常,而是返回NULL。使用時要包含 <new>標頭檔。
該函數的第2形參是 struct nothrow_t { };它是個全域常對象 const nothrow_t nothrow; 用來作為 new 運算子的標誌,以區別前一個new.
3.placement new 放置new
>void*operator new(std::size_t ,void *); void operator delete( void * ,void *);
該運算子是在已指派的記憶體上重新構造對象,因為不分配記憶體,所以不必擔心分配失敗。唯一的工作是調用建構函式。要包含 <new>標頭檔。
# include <new> # include <iostream> void main() { using namespace std; char * p = new(nothrow) char [4]; if (p == NULL) { cout < <“allocte failed” < <endl; exit( -1 ); } // ... long * q = new(p)long(1000); delete [ ]p; //只釋放 p,不要用q釋放。 }
p和q僅僅是首址相同,所構建的對象可以類型不同。所“放置”的空間應小於原空間,以防不測。當”放置new”超過了申請的範圍,Debug版下會掛機,但Release版竟然能運行而不出錯!
該運算子的作用是:只要第一次分配成功,不再擔心分配失敗。
# include <new> # include <iostream> void main() { using namespace std; char * p = new(nothrow) char [100]; if (p == NULL) { cout < <“allocte failed” < <endl; exit( -1 ); } long * q1 = new(p)long(100); // 使用q1 ... int * q2 = new(p) int[100/sizeof(int) ]; // 使用q2 ... ADT * q3 = new(p) ADT[100/sizeof(ADT) ]; // 使用q3 然後釋放對象 ... delete [ ]p; //只釋放空間,不再析構對象。 }
注意:使用該運算子構造的對象或數組,一定要顯式調用解構函式,不可用delete代替析構,因為placement new 的對象的大小不再與原空間相同。
# include <new> # include <iostream> void main() { using namespace std; char * p = new(nothrow) char [sizeof(ADT)+2]; if (p == NULL) { cout < <“allocte failed” < <endl; exit( -1 ); } // ... ADT * q = new(p) ADT; // ... // delete q; // 錯誤 q-> ADT::~ADT(); //顯式調用解構函式,僅釋放對象 delete [ ]p; //最後,再用原指標來釋放記憶體. }
placement new 的主要用途就是可以反覆使用一塊已申請成功的記憶體空間。這樣可以避免申請失敗的徒勞,又可以避免使用後的釋放。
特別要注意的是對於 placement new 絕不可以調用的delete, 因為該new只是使用別人替它申請的地方(只是個租房戶,不是房主。無權將房子賣掉)。釋放記憶體是nothrow new的事,即要使用原來的指標釋放記憶體