1.C++裏new分配空間失敗
C++裏,new是最常用的分配堆空間的操作符。
new和malloc的區別體現在這幾方面:
1)new是操作符,malloc是函數;
2)new和delete操作符對應,malloc則和free函數對應;
3)new可以直接調用構造函數,而malloc不可以;
4)new底層其實是調用了malloc函數;
5)new可以重載,如果重載後的new符號,生成空間可能會在用戶定義的地方。
一般來說,在現代計算機中,new很少失敗,因爲現在計算機一般是64位,而且內存足夠大,遠超比爾蓋茨所說的“64KB is enough”。但如果一直不停不住的分配空間,還是有可能遇到內存分配失敗的問題。
2.C++ new失敗機制
C++的new是由malloc的思想的基礎上衍化而來,最開始的new借鑑了malloc的規則。malloc分配失敗,會返回一個空指針。最開始的編譯器(如VC 6.0),也如果new失敗,也會返回一個空指針。
但隨着C++語言的發展,負責C++編譯器的開發者提出來另一套邏輯:即C++如果發生new失敗,不返回空指針,而是拋出錯誤。該錯誤一般爲bad_alloc錯誤。
所以,形如如下語句的錯誤,在新的C++編譯器中,會是無用的。
int *p = new int[SIZE];
if(nullptr == p) //在C++新標準的編譯器中會出問題
{
cerr << "Bad Alloc" << endl;
return 0;
}
在《Effect C++》裏,提倡這種寫法:
try
{
int *p = new int[SIZE];
}
catch(bad_alloc &memExp)
{
//失敗以後,要麼abort要麼重分配
cerr << memExp.what() << endl;
}
3.建議寫法
但我個人建議,既爲了兼容最開始的寫法,又防止新的內存分配機制失敗,而且,C++裏,拋異常並不是一個好的做法,我的建議寫法是如下:
int *p = new(std::nothrow) int[SIZE];
if(nullptr == p)
{
cerr << "Bad Alloc" << endl;
return;
}
這是一種兼容老版本語法並符合新標準的語法。
PS:
C++ 11的改動真的很大,C++也變成了我完全不熟悉的語言,真的是如他人所說“學的C++時間越長,越感到這種語言看不懂”。