c++中的set_new_handler和new_handler

当operator new申请一个内存失败的时候,它会进行如下的处理步骤:
    1、如果存在客户指定的处理函数,则调用处理函数(new_handler),如果不存在则抛出一个异常。

2、继续申请内存分配请求。
    3、判断申请内存是否成功,如果成功则返回内存指针,如果失败转向处理步骤1



为了自定义这个“用以处理内存不足”的函数new_handler,用户可以调用set_new_handler进行设置

这两个函数声明如下:

namespace std{

typedef void (*new_handler)();

new_handler set_new_handler(new_handler p) throw();

}

其中,new_handler是个typedef,定义一个函数指针,该函数没有参数,也没有返回值;

set_new_handler用于设置处理函数,设置p为当前处理函数,并返回之前的new_handler

当operator new无法满足内存分配需求时,它会不断调用new_handler函数,直到找到足够的内存。

因此,应该妥善设计new_handler函数,一个设计良好的new_handler必须做以下事情:

1、删除其它无用的内存,使系统具有可以更多的内存可以使用,为下一步的内存申请作准备。

实现此策略的办法是:程序一开始执行就分配一大块内存,当new_handler被调用时,将它们释放还给程序使用。

2、设置另外一个new_handler。

如果当前的new_handler不能够做到更多的内存申请操作,或者它知道另外一个new_handler可以做到,

则可以调用set_new_handler函数设置另外一个new_handler,这样在operator new下一次调用的时候,

可以使用这个新的new_handler。

3、卸载new_handler,使operator new在下一次调用的时候,因为new_handler为空抛出内存申请异常。

4、new_handler抛出自定义的异常

5、不再返回,调用abort或者exit退出程序



c++并不支持专属某一类的new_handler,但是如果需要,可以重载operator new,自己实现这个行为。

只需为class提供自己的set_new_handler和operator new即可。

在operator new中做如下事情:

1、首先调用标准的set_new_handler,自定义专属类的处理函数

2、调用global operator new,执行实际的内存分配。如果内存分配失败,刚才被安装的new_handler将被调用。

3、无论new成功还是失败,都必须在类自定义的operator new结束前恢复全局new_handler

这一部分的详细示例参考《effective c++》 条款49

时间: 2024-11-09 02:00:21

c++中的set_new_handler和new_handler的相关文章

VS2005内存泄漏检测方法[转载]

一.非MFC程序可以用以下方法检测内存泄露: 1. 程序开始包含如下定义: #ifdef _DEBUG #define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__) #else #define DEBUG_CLIENTBLOCK #endif   // _DEBUG #define _CRTDBG_MAP_ALLOC #include #include #ifdef _DEBUG #define new   DEBUG_CLI

定制类自己的的new_handler

C++中的new操作符首先使用operator new函数来分配空间,然后再在此空间上调用类的构造函数构造对象.当operator new无法分配所需的内存空间时,默认的情况下会抛出一个bad_alloc异常,在抛出这个异常之前,如果用户指定了错误处理函数即new_handler,则程序会先执行new_handler函数进行错误处理.为了设置这个错误处理函数,我们需要调用set_new_handler函数,它在std命名空间内的情况如下所示 namespace std{ typedef void

Effective C++ Notes(读书笔记)

1,视C++为一种语言联邦,大致分为4个部分: A)C.说到底C++仍是以C为基础.区块.语句.预处理器.内置数据类型.数组.指针等等统统来自C. B)Object-Oriented C++.这部分也就是C with Classes所诉求的:classes(包括构造函数和虚构函数).封装.继承.多态,虚函数等等. C)Template C++.这是C++的范型编程部分,tamplates威力强大,它给我们带来了崭新的编程范型,也就是所谓的TMP模板元编程. D)STL.STL是个template

读书笔记 effective c++ Item 49 理解new-handler的行为

1. new-handler介绍 当操作符new不能满足内存分配请求的时候,它就会抛出异常.很久之前,它会返回一个null指针,一些旧的编译器仍然会这么做.你仍然会看到这种旧行为,但是我会把关于它的讨论推迟到本条款结束的时候. 1.1 调用set_new_handler来指定全局new-handler 在operator new由于不能满足内存分配要求而抛出异常之前,它会调用一个客户指定的叫做new-handler的错误处理函数.(这也不是完全正确的.Operator new的真正行为更加复杂.

C++箴言:理解 new-handler的行为

当 operator new 不能满足一个内存分配请求时,它抛出一个 exception(异常).很久以前,他返回一个 null pointer(空指针),而一些比较老的编译器还在这样做.你依然能达到以前的目的(在一定程度上),但是我要到本文的最后再讨论它. 在 operator new 因回应一个无法满足的内存请求而抛出一个 exception 之前,它先调用一个可以由客户指定的被称为 new-handler 的 error-handling function(错误处理函数).(这并不完全确切

定制new 和 delete

1.了解new-handler的行为 当operator new 抛出异常以反映一个未满足的内存需求之前,他会先调用一个客户指定的错误处理函数,一个所谓的new-handler.为了指定这个“用以处理内存不足”的函数,客户必须调用set_new_handler,那个声明于<new>的一个标准程序库函数: namespace std{ typedef void (*new_handler)(); new_handler set_new_handler(new_handler p) throw()

《Effective C++》:条款49:了解new-handler的行为

C++内存是由程序员手动管理的,不像Java或.net有垃圾回收机制.C++内存管理主要是分配例程和归还例程(allocation and deallocation routines),即operator new和operator delete,还有一个配合的角色new-handler.当涉及到数组时,上面提到的operator new和operator delete就会变为operator new[]和operator delete[]. 内存管理在多线程环境下更为复杂,因为heap是一个可被

C++ 内存分配操作符new和delete详解

重载new和delete 首先借用C++ Primer 5e的一个例子: string *sp = new string("a value"); string *arr = new string[10]; 这其实进行了以下三步操作: new表达式调用一个名为operator new(或者operator new[])的标准函数,分配一块足够大的,原始的,未命名的内存空间来存储特定的类型或者对象的数组. 编译器运行相应的构造函数以构造这些对象,并且传入初值. 对象构造完毕后返回指向该对象

条款49:了解new-handle行为

多线程下的内存管理与单线程下是完全不同的,因为heap是一个可以被全局改动的资源,所以所有的线程都有可能去访问这一资源,这回导致很多的race_conditions. 当operator new未取得想要的内存的时候,会调用一个用户指定的处理函数,new_handler. 这个函数可以使用set_new_handler来进行指定. 1 namespace std{ 2 typedef void(*new_handler)();//没有参数以及返回值 3 new_handler set_new_h