条款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#_实现冒泡排序

    //排序方法类public class Bubble { ; public static void SBubble(ref int[] intArr) { ; outSize < intArr. ...

  2. WebService简单介绍(一)

    分布式系统或软件如何通信?使用WebService服务.说它是服务可以,web通信中间件也ok,web通信组件....... 特点 自包含 自描述 跨平台.跨语言 基于开放和标准 (用了xml,嗯,开 ...

  3. C#提取PPT文本——提取SmartArt中的文本、批注中的文本

    提取文本的情况在工作和学习中常会遇到,在前面的文章中,已经讲述了如何提取PPT中文本框里的文本,在本篇文章中,将介绍如何使用C#代码语言提取PPT文档中SmartArt和批注中的文本.同样的,程序里面 ...

  4. checkbox在vue中的用法小结

    关于checkbox多选框是再常见不过的了,几乎很多地方都会用到,这两天在使用vue框架时需要用到checkbox多选功能,实在着实让我头疼,vue和原生checkbox用法不太一样,之前对于vue插 ...

  5. Bootstrap 实战之响应式个人博客 (一)

    一.示例 1.主页 2.博客详情页 3.在线地址 在线地址:入口 Addition:这里使用github-page将自己的静态项目免费部署到线上. 如果你只是做一些简单的静态项目做展示,付出这么大的时 ...

  6. django项目环境搭建

    本文转载自: https://blog.csdn.net/xiaogeldx/article/details/89038299 在码云平台创建项目 版本控制的种类 主要使用github(最主流) 国内 ...

  7. WPF开源项目

    WPF有很多优秀的开源项目,我以为大家都知道,结果,问了很多人,其实他们不知道.唉,太可惜了! 先介绍两个比较牛逼的界面库 1.MaterialDesignInXamlToolkit Android风 ...

  8. Centos7VMware虚拟机最小化安装后,安装Tenda U12 USB无线网卡驱动

    前几天买下了Tenda U12 USB 无线网卡 ,想连接上无线玩玩,可惜买下折腾了一周才解决他它驱动问题,前后在VMware上装了十多次,测试了好几个内核版本才搞定,好了废话不多说,分享下我安装过程 ...

  9. 简说raid1 raid2 raid5 raid6 raid10的优缺点和做各自raid需要几块硬盘

    Raid 0:一块硬盘或者以上就可做raid0优势:数据读取写入最快,最大优势提高硬盘容量,比如3快80G的硬盘做raid0 可用总容量为240G.速度是一样.缺点:无冗余能力,一块硬盘损坏,数据全无 ...

  10. SQL SERVER-查询爆破sa密码的主机

    drop table if exists #sql create table #sql ( Logdatae ), processinfo ), [text] varchar(max) ) go IN ...