C 學習筆記 new失敗後的處理

2021-09-05 09:10:52 字數 1940 閱讀 1186

眾所周知,c++中使用new關鍵字申請記憶體成功時會返回申請的記憶體起始位址,並在該位址上呼叫建構函式。那麼,有考慮過失敗的情況嗎?

int *p = (int*)malloc(10000000000000000000);

if(null == p)

else

int* p = new[10000000000000000000];

if(null == p)

else

c語言

失敗:返回null

c++失敗:返回null或丟擲std::bad_alloc異常,結果視編譯器的不同而不同。

這是因為在早期的c++編譯器中為了相容c編譯器的方式而做出的行為,而在近代,c++由於支援丟擲異常來處理一些可預見的異常情況後,c++編譯器就將丟擲std::bad-alloc異常作為new失敗的行為,so,當申請失敗丟擲異常時程式就不會執行到申請失敗的處理分支中。

void my_new_handler()

void ex_func()

}

類層次範圍

單次動態記憶體分配

首先進行new/delete關鍵字的過載:

class test

~test()

void* operator new (size_t size) //throw()

void operator delete (void* p)

void* operator new (size_t size) throw()

void operator delete (void* p)

};

例項一:證明編譯器是否存在全域性的new_handler處理函式
void my_new_handler()

void ex_func_1()//證明編譯器是否帶有全域性的new_handler處理函式

}catch(const bad_alloc&)//證明是否會丟擲bad_alloc異常

}

根據上述結果可知,不同的編譯器確實存在差異,三款編譯器中只有bcc編譯器定義了全域性的預設new_handler函式,並在new失敗時丟擲異常。

void* operator new (size_t size) throw()//宣告後就只返回空指標,不丟擲異常

int* p = new(nothrow) int[10];//在指定空間申請記憶體並構造物件

// ... ...

delete p;

int bb[2] = ;

struct st

;st* pt = new(bb) st();//指明在bb位址上建立物件

pt->x = 1;

pt->y = 2;

cout << bb[0] << endl;//通過列印值證明是在bb上建立了物件

cout << bb[1] << endl;

pt->~st();//在位址上指明呼叫建構函式後需要手動呼叫析構函式

當使用new申請一塊記憶體失敗時,丟擲異常std::bad_alloc是c++標準中規定的標準行為,所以推薦使用try catch( std::bad_alloc ) 的處理方式。但是在一些老舊的編譯器中,卻不支援該標準,它會返回null,此時具有c傳統的判斷申請結果形式**便起了作用。所以,要針對不同的情形採取合理的處置方式,在工程中為了增強可移植性可以採取相應方式(不丟擲異常、new_handler函式處理)來統一new失敗的行為。

new記憶體失敗後的正確處理

應該有很多的程式設計師對比爾蓋茨的這句話有所耳聞 對於任何乙個人而言,640kb應當是足夠的了。640k ought to be enough for everybody.不幸的是,偉大的比爾蓋茨也失言了。隨著硬體水平的發展,記憶體變得越來越大,但是似乎仍不能滿足人們對記憶體日益增長的需求。所以呢,...

new和malloc申請記憶體失敗後的處理

1.c 標準 new 失敗是丟擲異常的,visual c 6.0中返回乙個null指標.使用new std nothrow 可以保證失敗時返回null 因此完全可以 define new new std nothrow 2.使用 malloc calloc 等分配記憶體的函式時,一定要檢查其返回值是...

new失敗時的處理

1.使用set new handler void nomemery std set new handler nomemery 注意 std和檔案中都含有set new handler函式。測試中發現兩set new handler都重寫或者只重寫其中乙個都可以解決問題。個人見解 使用std set ...