猫猫哥

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
//############################################################################
//  自定义new handler
/*
 * 1. 什么是
 *
 * New handler 是当operator new分配内存失败是调用的函数
 * 目的是帮助内存分配成功
 *   set_new_handler() 设置一个new handler并且返回当前的new handler.
 */
void* operator new(std::size_t size) throw(std::bad_alloc) {
   while (true) {
      void* pMem = malloc(size);   // 分配内存
      if (pMem) 
         return pMem;              // 成功则返回

      new_handler Handler = set_new_handler(0);  // 获取new handler
      set_new_handler(Handler);

      if (Handler)
         (*Handler)();            // 调用new handler
      else
         throw bad_alloc();       // 如果new handler为空,抛异常
   }
}
/* 
 * 所以new-handler 必须要做以下事情之一:
 * 1). 使更多的内存可用
 * 2). 设置一个不同的new-handler
 * 3). 卸载new-handler (即传一个null指针)
 * 4). 抛出一个bad_alloc异常或者派生类
 * 5). 终止程序
 */

int main() {
   int *pGiant = new int[10000000000L];
   delete[] pGiant;
}

OUTPUT:
terminate called after throwing an instance of 'std::bad_alloc'



void NoMoreMem() {
   std::cerr << "Unable to allocate memory, Bo." << endl;
   abort();
}
int main() {
   std::set_new_handler(NoMoreMem);
   int *pGiant = new int[10000000000L];
   delete[] pGiant;
}

OUTPUT:
Unable to allocate memory, Bo.




/*
 * 2. 类专用的new-handler
 */

class dog {
   int hair[10000000000L];
   std::new_handler origHandler;
   public:
   static void NoMemForDog() {
      std::cerr << "No more memory for doggy, Bo." << endl;
      std::set_new_handler(origHandler); // 抛异常之前把handler还原成老的
      throw std::bad_alloc;
   }
   void* operator new(std::size_t size) throw(std::bad_alloc) {
      origHandler = std::set_new_handler(NoMemForDog);   //替换handler,保存老的handler
      void* pV = ::operator new(size);   // 调用全局的operator new
      std::set_new_handler(origHandler); // 恢复老的handler
      return pV;
   }
};


int main() {
   std::tr1::shared_ptr<dog> pd(new dog()); 
   ...
}
posted on 2018-12-26 23:04  猫猫哥  阅读(622)  评论(0编辑  收藏  举报