zoukankan      html  css  js  c++  java
  • Effective C++学习心得——了解new-handler的行为

      当operator new无法满足某一内存分配需求时,它会抛出异常。以前它会返回一个null指针,某些旧式编译器目前也还那么做。当operator new抛出异常以反映一个未获满足的内存需求之前,它会先调用一个客户指定的错误处理函数,一个所谓的 "new-handler",当然operator new真正做的事情稍微更复杂些。为了指定这个"用以处理内存不足”的函数,客户必须调用set_new_handler,那是声明于<new>的一个标准程序库函数:

    namespace std
    {
        typedef void (*new_handler)();
        new_handler set_new_handler(new_handler p) throw();
    }

      new_handler 只是一个 typedef ,定义一个指针指向函数,该函数没有参数也不返回任何东西。set_new_handler 则是“获得一个 new_handler并返回一个new_handler”的函数。set_new_handler 声明尾部的 “throw()” 是一份异常处理明细,表示该函数不抛出任何异常。

      set_new_handler的参数是个指针,指向operator new无法分配足够内存时应该被调用的函数,其返回值是个指针,指向set_new_handler被调用前正在执行的 “new-handler” 函数。

      为了便于理解,如下:

    void oom()
    {
        std::cerr << "out of memory!!";
        std::about();
    }
    
    int main()
    {
        std::set_new_handler(oom);
        int *needBigMemory = new int [5000000000L];
        ...
        return 0;
    }

      在这个例子中,当 operator new 无法为5000000000个整数分配足够空间的时候,oom() 函数会被调用,程序输出 “out of memory!!” 后夭折,如果在写出错误信息到 cerr 的过程中必须动态分配内存,则会进入上一篇中提到的 oom_malloc() 函数中的死循环,不断尝试释放、再配置、再释放、在配置......

      当 operator new 无法满足内存申请时,它会不断调用“new-handler”函数(也就是不停在oom_malloc()函数中死循环),直到找到足够内存。由此我们必须设计良好的 new-handler 函数。具体如下:

      1、让更多内存可被使用,这边造成了operator new内的下一次内存分配动作可能成功。实现此策略的一个做法是,程序一开始执行就分配一大块内存,而后当 new-handler 第一次被调用,将它们释还给程序使用。

      2、安装另一个 new-handler。如果目前这个 new-handler 无法取得更多可用内存,或许它知道另外哪个 new-handle 有此能力。如此,目前这个new-handler 就可以安装另外那个 new-handler 以替换自己。下次当operator new 调用 new-handler,调用的将是最新安装的那个。(如果 new-handler 修改自己的行为,于是当它下次被调用,就会做某些不同的事。为达此目的,做法之一是令 new-handler 修改“会影响new-handler 行为”的static数据、namespace数据或global数据)

      3、卸除 new-handler,也就是将null指针传给 set_new_handler。一旦没有安装任何 new-handler, operator new 会在内存分配不成功时抛出异常。

      4、抛出 bad_alloc (或派生自 bad_alloc) 的异常。这样的异常不会被operator new 捕捉,因此会被传播到内存索求处。

      5、不返回,通常调用 abort() 或 exit(0)。

    既然选择了远方,便只顾风雨兼程
  • 相关阅读:
    mysql数据库汉字首字母简拼全拼
    window.showModalDialog刷新父窗口和本窗口的方法及注意
    c#.net语句e.Row.RowType == DataControlRowType.DataRow是什么含义?
    SQL 拿到一天内的数据
    在线脚本编辑器
    输入正确的邮箱地址
    jquery中的$(document).ready()方法和window.onload方法区别
    转载从XML文件中读取数据绑定到DropDownList
    GridView中DropDownList联动
    For 循环 和Foreach 的区别
  • 原文地址:https://www.cnblogs.com/Forever-Road/p/6808875.html
Copyright © 2011-2022 走看看