c++中的new_handler


原文地址: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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM