条款49:了解new-handler的行为

  • 当operator new无法分配出内存会抛出异常std::bad_alloc
  • 抛出异常前会反复调用用户自定义的new-handler函数直至成功分配内存
// 自定义new_handler函数
void outOfMem() {
cerr << "Unable to satisfy request for memory" << endl;
abort();
}
//测试
int main() {
set_new_handler(outOfMem); //写入new_handler函数
int* pBigDataArray = new int[100000000000000000L];
return 0;
} //输出 :Unable to satisfy request for memory //声明于<new>中的标准程序函数
namespace std {
typedef void (*new_handler) ();
new_handler set_new_handler(new_handler p) throw();
}
  • 为不同的class写不同的new-handler函数
#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std; class NewHandlerHolder {
public:
explicit NewHandlerHolder(new_handler nh)
: handler(nh) {} ~NewHandlerHolder() {std::set_new_handler(handler);}
private:
new_handler handler;
NewHandlerHolder(const NewHandlerHolder&) {}
NewHandlerHolder& operator= (const NewHandlerHolder&) {} }; template<typename T>
class NewHandlerSupport {
public:
static new_handler set_new_handler(new_handler p) throw();
static void* operator new[](size_t size) throw(bad_alloc);
private:
static new_handler currentHandler;
}; template<typename T>
new_handler NewHandlerSupport<T>::currentHandler = 0; template<typename T>
new_handler NewHandlerSupport<T>::set_new_handler(new_handler p) throw() {
new_handler oldHandler = currentHandler;
currentHandler = p;
return oldHandler;
} template<typename T>
void* NewHandlerSupport<T>::operator new[](size_t size) throw(bad_alloc) {
NewHandlerHolder h(std::set_new_handler(currentHandler));
return ::operator new[](size);
} class Widget : public NewHandlerSupport<Widget>{ }; void outOfMem() {
cerr << "Unable to satisfy request for memory" << endl;
abort();
} int main() {
Widget::set_new_handler(outOfMem);
Widget* pwl = new Widget[100000000000L]; return 0;
}

条款50:了解new和delete的合理替换时机

  • 有许多理由需要自定new和delete,包括改善性能、对heap运用错误进行调试、手机heap使用信息

条款51:编写new和delete时需固守常规

  • operator new 应该包含一个无穷循环,并在其中尝试分配内存,如果无法满足内存需求,就调用new-handler函数,且要有能力处理 0 bytes申请。
  • operator delete应该在收到null指针时不做任何事情 

条款52:写了placement new也要写placement delete

  • 当写new的表达式\(Widget* pw = new Widget\)时,两个函数被调用

    • 一个是用以分配内存的 operator new
    • 另一个是Widget的default构造函数
  • 如果在调用构造函数失败,编译器会寻找一个“带相同额外参数”的operator delete,找不到调用不了,会造成资源泄漏

《Effective C++》定制new和delete:条款49-条款52的更多相关文章

  1. Effective C++ —— 定制new和delete(八)

    STL容器所使用的heap内存是由容器所拥有的分配器对象管理,不是被new和delete直接管理.本章并不讨论STL分配器. 条款49 : 了解new-handler的行为 当operator new ...

  2. 【effective c++】定制new和delete

    条款49: 了解new-handler的行为 operator new 和 operator delete只适合用来分配单一对象.array所用的内存由operator new[]分配出来,并由ope ...

  3. EC读书笔记系列之19:条款49、50、51、52

    条款49 了解new-handler的行为 记住: ★set_new_handler允许客户指定一个函数,在内存分配无法获得满足时被调用 ★Nothrow new是一个颇为局限的工具,∵其只适用于内存 ...

  4. 八、定制new和delete

    条款49:了解new-handler的行为 new异常会发生什么事? 在旧式的编译器中,operator new分配内存失败的时候,会返回一个null指针.而现在则是会抛出一个异常. 而在抛出这个异常 ...

  5. STL笔记(5)条款49:学习破解有关STL的编译器诊断信息

    STL笔记(5)条款49:学习破解有关STL的编译器诊断信息 条款49:学习破解有关STL的编译器诊断信息 用一个特定的大小定义一个vector是完全合法的, vector<int> v( ...

  6. 高效C++:定制new和delete

    内存的申请和释放,C++从语言级别提供了new和delete关键字,因此需要了解和熟悉其中的过程. 了解new-handler的行为 set_new_handler可以指定一个函数,当申请内存失败时调 ...

  7. Effective C++: 08定制new和delete

    49:了解new-handler的行为 当operator new无法满足某一内存分配需求时,它会抛出异常(以前会返回一个null).在抛出异常之前,它会调用一个客户指定的错误处理函数,也就是所谓的n ...

  8. Effective C++ -----条款49:了解new-handler 的行为

    set_new_handler允许客户指定一个函数,在内存分配无法获得满足时被调用. Nothorw new 是一个颇为局限的工具,因为它只适用于内存分配:后继的构造函数调用还是可能抛出异常.

  9. Effective C++:条款27——条款

    条款27:尽量少做转型动作 单一对象可能拥有一个以上的地址!

随机推荐

  1. C#服务器控件 IsReadOnly 和 Visibility,IsEnable 的区别

    IsReadOnly  适用于“输入.输出”类控件,比如TextBox类, 可以当做文本输入,也可以通过后台代码进行输出. 设置 IsReadOnly(只读) = true 后,该控件只允许输出,不允 ...

  2. C# 在PPT幻灯片中创建图表

    图表能够很直观的表现数据在某个时间段的变化趋势,或者呈现数据的整体和局部之间的相互关系,相较于大篇幅的文本数据,图表更增加了我们分析数据时选择的多样性,是我们挖掘数据背后潜在价值的一种更为有效地方式. ...

  3. Android开发——绘图基础

    前言: Android中绘图基本三个类,分别是Paint(画笔),Path(路径),Canvas(画布),这三个也是自定义View经常会使用到的类 个人理解,Canvas画布这个翻译其实不太好,这个类 ...

  4. Java学习笔记之——TreeMap

    TreeMap: 特点:存储时,按照键排序 底层使用一个红黑树,特殊的而二叉树 排序跟comparable,comparator有关系 如果需要在添加时进行排序,使用hashMap即可 构造方法: T ...

  5. mac 安装protobuf,并编译为java,c++,python

    1.下载地址:https://code.google.com/p/protobuf/downloads/list 另外,可以查看这个链接查看中文更多内容:http://www.cnblogs.com/ ...

  6. elasticsearch常用命令

    elasticsearch的rest访问格式: curl -X<REST Verb> <Node>:<Port>/<Index>/<Type> ...

  7. 使用VsCode自带的Emmet语法

    新建html文件,保存之后,输入"!",按Tap(或Enter)键,自动生成HTML结构 标签只要直接输入标签名(不要输入<>),按Tap(或Enter)键自动生成完整 ...

  8. VSCode的Python扩展下程序运行的几种方式与环境变量管理

    在VSCode中编写Python程序时,由于有些地方要使用环境变量,但是发现设置的环境变量有时不起作用,花了点时间研究了一下,过程不表,直接说结论. 首先,环境变量的设置,Python扩展中有三种方式 ...

  9. linq 左连接后实现与主表一对一关系数据

    var query1 = from r in _residentRepository.GetAll() join i in _inLogRepository.GetAll() on r.Id equa ...

  10. 从Excel中导入数据时,提示“未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序”的解决办法

    注意,64位系统,用64位的补丁文件; https://www.cnblogs.com/A2008A/articles/2438962.html 操作系统:使用的是64位的Windows Server ...