了解new_handler
来源:互联网 发布:青少年编程创业 编辑:程序博客网 时间:2024/04/30 19:19
了解new_handler
内存管理是C++的难点,也是重点,今天就把new_handler的学习笔记和大家分享。请大家多多指点。
参考书籍:《Effective C++》
- 了解new_handler
- 关于new_handler
- new_handler的定义
- new_handler的简单使用实例
- 为类设置自己的new_handler
- 用继承和模板为类提供其独有的new_handler
- 关于new_handler
关于new_handler
new_handler位于头文件< new >中
当new无法成功申请内存,在抛出异常之前,new会调用一个系统默认或用户指定的错误处理函数,也就是这里的new_handler。我们可以通过set_new_handler来设置我们的错误处理函数。
new_handler的定义
namespace std{ typedef void(*new_handler)(); new_handler set_new_handler(new_handler) throw();}
所以new_handler是一个函数指针。而set_new_handler是用来设置新的new_handler,后返回旧的new_handler的函数。
new_handler的简单使用实例
使用的是vs2015
#include <iostream>#include <new>#include <windows.h>void OutOfMem() { std::cout << "内存空间不足" << std::endl; abort();}int main() { std::set_new_handler(OutOfMem); char *pint(new char[0x7fffffff]); return 0;}
当new发现没有足够内存空间时,调用new_handler指向的函数,打印出“内存空间不足”后 abort() 。如果没有 abort() 它的行为又是怎样的呢?
如图所示,他将会无止境的调用OutOfMem。当new无法满足内存申请的要求时,他会不断地调用new_handler,直至new找到一片足够大的内存返回为止。
为类设置自己的new_handler
为类实现自己的new_handler将通过重载 局部的new 实现。
看一个例子:
#include <iostream>#include <new>#include <windows.h>//这里用于保存 默认的全局的new_handler,当该类的析构函数调用时,将handler还原//相当于一个简易的GCclass HandlerHolder {public: explicit HandlerHolder(std::new_handler nh) :handler(nh) {} ~HandlerHolder() { std::set_new_handler(this->handler); } //将保存的默认的全局handler还原 HandlerHolder(const HandlerHolder&) = delete; //阻止拷贝行为 HandlerHolder&operator=(const HandlerHolder&) = delete;//阻止拷贝行为private: std::new_handler handler;//保存 new_handler,这里用来保存全局的new_handler};class Demo {public: static std::new_handler set_new_handler(std::new_handler nh) { std::new_handler oldhandler = cur_handler; cur_handler = nh; return oldhandler; } void * operator new(size_t size)throw(std::bad_alloc){ HandlerHolder h(std::set_new_handler(cur_handler)); //handlerHolder 保存旧版的new_handler, //当new结束时,handlerHolder的析构函数将被调用, //new_handler将被还原为全局的new_handler return ::operator new(size); //调用全局的new } void *operator new[](size_t size) { return operator new(size); }private: static std::new_handler cur_handler;//保存当前的new_handler};std::new_handler Demo::cur_handler(nullptr);void OutOfMem() { std::cout << "Run out of Men" << std::endl; abort();}int main() { Demo::set_new_handler(OutOfMem); Demo * p(new Demo[0x7fffffff]); //1.当new发生时,首先调用Demo的operator new[]跳转到operator new,这时在new函数中,new_handler被装载 //2.如果new失败,将调用OutOfMen;如果new成功,将返回内存地址,HandlerHolder将被析构,在析构时调用set_new_handler // 还原装载OutOfMem之前的new_handler return 0;}
在Demo::set_new_handler的参数中,我们可以传入各种自定义的内存分配失败的处理方法。在《Effective C++》中,为我们呈现了几种:
1.让更多的内存可以被使用(也就是清理内存,让出更多的空间给这里的内存分配操作)
2.安装另一个new_handler(当这个new_handler无法处理当前分配失败的情况时,我们可以装在另外一个new_handler试图处理这种情况)
3.卸载new_handler(如果当前的new_handler确实无法处理当前错误,那么就将当前的new_handler卸载,例如nullptr,让new抛出bad::alloc的异常)
4.直接抛出bad::alloc的异常
5.调用abort()或exit()直接终止程序
用继承和模板为类提供其独有的new_handler
#include <iostream>#include <new>#include <Windows.h>//这里用于保存 默认的全局的new_handler,当该类的析构函数调用时,将handler还原//相当于一个简易的GCclass HandlerHolder {public: explicit HandlerHolder(std::new_handler nh) :handler(nh) {} ~HandlerHolder() { std::set_new_handler(this->handler); } //将保存的默认的全局handler还原 HandlerHolder(const HandlerHolder&) = delete; //阻止拷贝行为 HandlerHolder&operator=(const HandlerHolder&) = delete;//阻止拷贝行为private: std::new_handler handler;//保存 new_handler,这里用来保存全局的new_handler};template<typename T>class NewHandler {public: static std::new_handler set_new_handler(std::new_handler nh) { std::new_handler oldhandler = cur_handler; cur_handler = nh; return oldhandler; } void *operator new(size_t size){ HandlerHolder holder(std::set_new_handler(cur_handler)); return ::operator new(size); } void *operator new[](size_t size) { return operator new(size); }private: static std::new_handler cur_handler;};template<typename T>std::new_handler NewHandler<T>::cur_handler(nullptr);class Demo :public NewHandler<Demo> {public:private: static std::new_handler cur_handler;//保存当前的new_handler};void OutOfMem() { std::cout << "Run out of Mem" << std::endl; abort();}int main() { Demo::set_new_handler(OutOfMem); Demo * p(new Demo[0x7fffffff]); return 0;}
- 了解new_handler
- 了解new_handler的所作所为
- C++ - 了解new_handler的所作所为
- 了解new_handler的行为 set_new_handler
- new_handler
- new_handler
- 改善C++ 程序的150个建议学习之建议31:了解new_handler的所作所为
- new_handler & set_new_handler
- C++中new_handler
- C++中new_handler
- Item 49 new_handler
- C++中new_handler
- new_handler 问题的笔记
- c++中的set_new_handler和new_handler
- c++中的set_new_handler和new_handler
- c++中的set_new_handler和new_handler
- c++中的set_new_handler和new_handler
- c++中的set_new_handler和new_handler
- 升级Ubuntu系统
- CentOS Oracle11gR2 设置开机自启动
- 二叉排序树和堆的区别
- maven之仓库(repository)导出c盘
- 清朝皇帝和八旗制度
- 了解new_handler
- Service 生命周期基础
- 微信界面
- FragmentPagerAdapter+fragment错位的问题解决
- eclipse不能创建tomcat服务器的解决办法
- ButterKnife是一个专注于Android系统的View注入框架
- TCP/IP网络配置实验
- hibernate的直接加载xml的方式
- Android开发之BroadcastReceiver详解