1. 程式人生 > >C++進階--自定義new handler

C++進階--自定義new handler

tput code cer urn 卸載 可用 幫助 malloc dog

//############################################################################
//  自定義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()); 
   ...
}

C++進階--自定義new handler