C++ new delete new[] delete[]

C++不支持类专属的new-handler,类需要自定义operator new和set_new_handler静态成员函数来使用其专属的new-handler。


throwing (1)void* operator new (std::size_t size) throw (std::bad_alloc);
nothrow (2) void* operator new (std::size_t size, const std::nothrow_t& nothrow_value) throw();
placement (3) void* operator new (std::size_t size, void* ptr) throw();


一、分类:

        1)void *operator new(std::size_t) throw(std::bad_alloc);

              -------- 失败时,先执行std::new_handler,如果还是失败,则抛出异常。

--------  返回值不会为空!判断指针是否为空是不正确的。


        2)void *operator new(std::size_t, void*) throw();

              -------- 这是通用的placement new;void *可以被替换。

              -------- 必须定义一个带有同样参数的operator delete,否则执行delete时,不会有任何动作;


        3)void *operator new(std::size_t, const std::nothrow_t&) throw();---基本无用

              ------- 不抛出异常;可以判断返回值是否为空。

              ------- 使用方式如 new (std::nothrow) classname;

              ------- 只保证operator new不抛异常,但无法保证申请成功后的"构造函数"不抛异常;所以无用。


检查申请内存的一般方式:

1) new (std::nothrow) xxx;  --- 相当于是std::nothrow_t x; operator new (sizeof(int), x);

2) 使用placement new;--- 它是先申请内存,再调用new (pointer) x;

3) 定义template<class t> class newhandlersupport; 在其中定义operator new和set_new_handler。

             class x: public newhandlersupport<x>;

4) 在x中定义operator new。采用如x *px1 = new (specialerrorhandler) x;  方式。

class x {

public:

  void f();

  static void * operator new(size_t size, new_handler p); // 重载了new操作符,new-hander为new的出错处理)函数

  static void * operator new(size_t size)

  { return ::operator new(size); }

};

二、为什么替换new,delete?替换时需要注意遵循哪些规则?是否有开源内存管理器?

       1、理由:

        检测错误;

        收集统计信息;

        提高速度;

        节约内存;(泛用型内存管理器往往使用更多内存)

        为了拟补缺省分配器中的非最佳齐位(如,double在8字节对齐情况下性能好)

        为了将对象成簇集中

        非传统行为

      2、规则

         支持分配0字节内存,转化为分配1字节内存;

         循环执行分配,直到以下情况:成功?抛出异常? 其中循环执行new-handling函数

         还需要考虑operator new被子类继承的情况,是否影响子类执行。

         operator new[]更复杂,还需要如何考虑存放数组元素的个数。

         删除null指针永远安全。

         normal new,placement new,nothrow new必须都定义。

      3、

        如boost程序库的Pool就是,它对于最常见的“分配大量小型对象”很有帮助。

        ACE中也有各类内存分配,如内存池ACE_Cached_Allocator

三、补充:

   C++11版本,new数组失败会得到如下异常bad_array_new_length,继承自std::bad_alloc。

  • 数组长度小于0
  • 数组长度大于限制
  • 初始化列表大于数组长度

你可能感兴趣的:(C++,c,delete)