operator new之错误处理函数new_handler
2016-07-10 19:52
337 查看
就像可以用atexit来注册main的退出处理函数一样,我们也可以用std::set_new_handler来注册operator new的错误处理函数。
当operator new无法满足某一内存分配需求时,operator new会抛出异常。
但是当operator new无法满足某一内存分配需求而抛出异常之前,会先调用一个用户指定的错误处理函数,即所谓的new-handler。
即operator new无法满足内存分配需求--->(循环)调用执行用户指定的错误处理函数new-handler--->operator
new抛出异常
用户可以调用std::set_new_handler接口指定这个“用以处理内存不足”的函数new-handler,
new-handler是声明于<new>的一个标准程序库函数,如下所示:
可知:
1)new_handler是通过typedef定义出的一个指针指向函数,该函数不返回任何东西
2)set_new_handler:则是获得一个new_handler并返回一个new_handler的函数
set_new_handler函数的实现大概如下所示:
3)声明式的尾端throw()是一份异常明细,表示该函数不抛出任何异常
注:当operator new无法满足内存申请时,operator new会不断反复调用new-handler函数,直到找到足够内存。
示例如下:
![](https://img-blog.csdn.net/20160710194444315?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
通过以上测试可知,当operator new无法满足内存分配时,如果你通过std::set_new_handler设置了operator
new的错误处理函数new_handler后,就会重复调用new_handler函数直到找到足够的内存(如果你在new_handler内调用了abort或者exit则new_handler会只被调用一次)。
跟进一步得出结论,设计一个良好的new_handler函数是很重要的。
new_handler能选择以下几个处理方式中的一个方式进行处理是比较合理的,也是应该的。
处理方式1:让更多内存被使用
程序刚开始时就申请分配一大块内存,当new_handler被调用时就释放它还给程序使用。
处理方式2:安装另一个new_handler
如果new_handler1无法处理时,就在new_handler1内部调用set_new_handler设置new_handler2来处理,下次就会调用new_handler2来处理。
处理方式3:卸载new_handler
std::set_new_handler(NULL)来卸载new_handler,则operator new在内存分配失败时不会调用错误处理函数new_handler而直接抛出异std::bad_alloc并且Abort掉程序。
处理方式4:抛出std::bad_alloc或者派生自std::bad_alloc的异常。
这样异常不会被operator new捕捉,因此会被传播到内存索求处。
处理方式5:调用abort或exit
下面这五种处理方式中的几种方式,进行编码实现。
处理方式2:安装另一个new_handler
如果new_handler1无法处理时,就在new_handler1内部调用set_new_handler设置new_handler2来处理,下次就会调用new_handler2来处理。
测试结果如下所示:
![](https://img-blog.csdn.net/20160710194741098?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
处理方式3:卸载new_handler
std::set_new_handler(NULL)来卸载new_handler,则operator new在内存分配失败时不会调用错误处理函数new_handler。
测试结果如下所示:
![](https://img-blog.csdn.net/20160710194903755?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
处理方式5:调用abort或exit
![](https://img-blog.csdn.net/20160710195022614?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
在C++开发的工程项目中,一般可能需要对具体class注册自定义的new_handler,具体可以参考《Effective C++ 改善程序与设计的55个具体做法》。
(完)
当operator new无法满足某一内存分配需求时,operator new会抛出异常。
但是当operator new无法满足某一内存分配需求而抛出异常之前,会先调用一个用户指定的错误处理函数,即所谓的new-handler。
即operator new无法满足内存分配需求--->(循环)调用执行用户指定的错误处理函数new-handler--->operator
new抛出异常
用户可以调用std::set_new_handler接口指定这个“用以处理内存不足”的函数new-handler,
new-handler是声明于<new>的一个标准程序库函数,如下所示:
namespace std { typdef void (*new_handler)(); new_handler set_new_handler(new_handler p) throw(); }
可知:
1)new_handler是通过typedef定义出的一个指针指向函数,该函数不返回任何东西
2)set_new_handler:则是获得一个new_handler并返回一个new_handler的函数
set_new_handler函数的实现大概如下所示:
new_handler set_new_handler(new_handler p) throw { new_handler oldHandler = m_curHandler; m_curHandler = p; return oldHandler; }
3)声明式的尾端throw()是一份异常明细,表示该函数不抛出任何异常
注:当operator new无法满足内存申请时,operator new会不断反复调用new-handler函数,直到找到足够内存。
示例如下:
#include <stdlib.h> //for abort() #include <iostream> void outOfMem() { std::cerr<<"operator new unable to satisfy request for memory, try allocate memory again.\n"; } int main() { std::set_new_handler(outOfMem ); int *buf = new int[1000000000L]; Delete []buf; return 0; }测试结果如下所示:
通过以上测试可知,当operator new无法满足内存分配时,如果你通过std::set_new_handler设置了operator
new的错误处理函数new_handler后,就会重复调用new_handler函数直到找到足够的内存(如果你在new_handler内调用了abort或者exit则new_handler会只被调用一次)。
跟进一步得出结论,设计一个良好的new_handler函数是很重要的。
new_handler能选择以下几个处理方式中的一个方式进行处理是比较合理的,也是应该的。
处理方式1:让更多内存被使用
程序刚开始时就申请分配一大块内存,当new_handler被调用时就释放它还给程序使用。
处理方式2:安装另一个new_handler
如果new_handler1无法处理时,就在new_handler1内部调用set_new_handler设置new_handler2来处理,下次就会调用new_handler2来处理。
处理方式3:卸载new_handler
std::set_new_handler(NULL)来卸载new_handler,则operator new在内存分配失败时不会调用错误处理函数new_handler而直接抛出异std::bad_alloc并且Abort掉程序。
处理方式4:抛出std::bad_alloc或者派生自std::bad_alloc的异常。
这样异常不会被operator new捕捉,因此会被传播到内存索求处。
处理方式5:调用abort或exit
下面这五种处理方式中的几种方式,进行编码实现。
处理方式2:安装另一个new_handler
如果new_handler1无法处理时,就在new_handler1内部调用set_new_handler设置new_handler2来处理,下次就会调用new_handler2来处理。
#include <stdlib.h> //for abort() #include <iostream> void handle_outOfMem2() { std::cerr<<__FUNCTION__<<":operator new unable to satisfy request for memory, try allocate memory again.\n"; } void handle_outOfMem() { std::cerr<<__FUNCTION__<<":operator new unable to satisfy request for memory, try allocate memory again.\n"; std::set_new_handler(handle_outOfMem2); } int main() { std::set_new_handler(handle_outOfMem ); int *buf = new int[1000000000L]; delete []buf; return 0; }
测试结果如下所示:
处理方式3:卸载new_handler
std::set_new_handler(NULL)来卸载new_handler,则operator new在内存分配失败时不会调用错误处理函数new_handler。
#include <stdlib.h> //for abort() #include <iostream> void handle_outOfMem() { std::cerr<<__FUNCTION__<<":operator new unable to satisfy request for memory, try allocate memory again.\n"; std::set_new_handler(NULL); } int main() { std::set_new_handler(handle_outOfMem ); int *buf = new int[1000000000L]; delete []buf; return 0; }
测试结果如下所示:
处理方式5:调用abort或exit
#include <stdlib.h> //for abort() #include <iostream> void handle_outOfMem() { std::cerr<<"operator new allocate memory failed, try again.\n"; abort(); } int main() { std::set_new_handler(handle_outOfMem ); int* buf = new int[1000000000000000L]; delete []buf; return 0; }测试结果如下所示:
在C++开发的工程项目中,一般可能需要对具体class注册自定义的new_handler,具体可以参考《Effective C++ 改善程序与设计的55个具体做法》。
(完)
相关文章推荐
- Dreamweaver第一天 - 网站前期企划篇 - 网站企划概念
- linux终端输出彩色字体
- dockers
- JDK的windows和Linux版本之下载
- HADOOP-RPC机制
- 毕业工作五年的总结和感悟(中)
- 闲话Linux系统安全(二)——强制访问控制(MAC)
- Linux下查看、关闭及开启防火墙命令
- Linux命令(005) -- kill、pkill和killall的比较
- Linux唤醒抢占----Linux进程的管理与调度(二十三)
- Linux学习——NFS自动挂载
- hadoop命令,学到哪记到哪。
- apache的配置优化
- linux arm移植触摸屏tslib
- zabbix监控web
- Centos6.5安装mysql不能启动,应该安装mysql-server
- Linux服务器,PHP的10大安全配置实践
- [Meet In Middle] BZOJ 2679 [Usaco2012 Open]Balanced Cow Subsets
- ASP.NET Core 发布至Linux生产环境 Ubuntu 系统
- Linux进程上下文切换过程context_switch详解--Linux进程的管理与调度(二十一)