原文地址:http://blog.csdn.net/wzq981264/article/details/673630
在過去或者傳統的模式中,當operator new不能滿足一個內存分配請求的時候,它會返回一個空指針,但是現在如果operator new不能滿足一個內存分配請求的時候,會拋出一個異常,這個時候我們可不可以自己定制處理策略呢?這正是new_handler的作用所在,具體情況在后面詳細道來。
當operator new申請一個內存失敗時,它會進行如下的處理步驟:
1、如果存在客戶指定的處理函數,則調用處理函數(new_handler),如果不存在則拋出一個異常。new_handler的模型為:void (*new_handler)()。
2、繼續申請內存分配請求。
3、判斷申請內存是否成功,如果成功則返回內存指針,如果失敗轉向處理步驟1。
可以用如下的代碼表示:
全局部分:
void (*class_new_oom_handler)();
......
operator new執行方法中:
void (*my_new_oom_handler)(); void *result; for( ; ; ) { my_new_oom_handler = class_new_oom_handler; if( my_new_oom_handler == NULL ) THROW_BAD_NEW; //如果沒有設置自定義處理函數,則默認的處理方式為拋出一個異常 (*my_new_oom_handler)(); //調用自定義內存異常處理函數 result = malloc( n ); //繼續申請內存 if( result ) return( result ); //申請成功,返回指針 }
說了這么多,大家一定會問,那我怎么設置這個處理函數(new_handler),通過“void set_new_handler( void(*new_handler)()) throw();”進行設置,它定義在<new>標准函數庫中:
namespace std { void (*new_handler)(); void set_new_handler( new_handler )throw(); }
//error-handling function void MemErrorHandling() { std::cerr << "Failed to allocate memory.\n"; std::abort(); } ... ... std::set_new_handler(MemErrorHandling);
現在我們知道了new操作失敗后,系統地大概處理流程,以及怎么設置用戶自定義處理函數,但是我們究竟可以在new_handler中做些什么處理呢?
1、刪除其它無用的內存,使系統具有可以更多的內存可以使用,為下一步的內存申請作准備。
2、設置另外一個new_handler。如果當前的new_handler不能夠做到更多的內存申請操作,或者它知道另外一個new_handler可以做到,則可以調用set_new_handler函數設置另外一個new_handler,這樣在operator new下一次調用的時候,可以使用這個新的new_handler。
3、卸載new_handler(通過set_new_handler(0)),使operator new在下一次調用的時候,因為new_handler為空拋出內存申請異常。
4、拋出自定義異常。
5、不再返回,調用abort或者exit退出程序。
參考:
1、http://www.bc-cn.net/Article/kfyy/cjj/jszl/200604/4002.html