std::nothrow
1、在内存不足时,new (std::nothrow)并不抛出异常,而是将指针置NULL。
若不使用std::nothrow,则分配失败时程序直接抛出异常。
2、使用方式:
1 #include2 #include // for std::cerr 3 #include // for std::exit() 4 Task * ptask = new (std::nothrow) Task; 5 if (!ptask) 6 { 7 std::cerr<<"allocation failure!"; 8 std::exit(1); 9 } 10 //... allocation succeeded; continue normally
1 #include2 std::nothrow_t nt; 3 Task * ptask = new (nt) Task; //user-defined argument 4 if (!ptask) 5 //...
3、分配失败是非常普通的,它们通常在植入性和不支持异常的可移动的器件中发生更频繁。因此,应用程序开发者在这个环境中使用nothrow new来替代普通的new是非常安全的。
4、一种宏实现的方式,取自ACE:
1 # define ACE_nothrow ::std::nothrow 2 # define ENOMEM 12 3 # define errno (* (ACE_CE_Errno::instance ())) 4 5 #if defined (ACE_NEW_THROWS_EXCEPTIONS) 6 # if defined (ACE_HAS_NEW_NOTHROW) 7 # define ACE_NEW_RETURN(POINTER,CONSTRUCTOR,RET_VAL) \ 8 do { POINTER = new (ACE_nothrow) CONSTRUCTOR; \ 9 if (POINTER == 0) { errno = ENOMEM; return RET_VAL; } \10 } while (0)11 # define ACE_NEW(POINTER,CONSTRUCTOR) \12 do { POINTER = new(ACE_nothrow) CONSTRUCTOR; \13 if (POINTER == 0) { errno = ENOMEM; return; } \14 } while (0)15 # define ACE_NEW_NORETURN(POINTER,CONSTRUCTOR) \16 do { POINTER = new(ACE_nothrow) CONSTRUCTOR; \17 if (POINTER == 0) { errno = ENOMEM; } \18 } while (0)19 20 # else21 22 # define ACE_NEW_RETURN(POINTER,CONSTRUCTOR,RET_VAL) \23 do { try { POINTER = new CONSTRUCTOR; } \24 catch (ACE_bad_alloc) { ACE_del_bad_alloc errno = ENOMEM; POINTER = 0; return RET_VAL; } \25 } while (0)26 27 # define ACE_NEW(POINTER,CONSTRUCTOR) \28 do { try { POINTER = new CONSTRUCTOR; } \29 catch (ACE_bad_alloc) { ACE_del_bad_alloc errno = ENOMEM; POINTER = 0; return; } \30 } while (0)31 32 # define ACE_NEW_NORETURN(POINTER,CONSTRUCTOR) \33 do { try { POINTER = new CONSTRUCTOR; } \34 catch (ACE_bad_alloc) { ACE_del_bad_alloc errno = ENOMEM; POINTER = 0; } \35 } while (0)36 # endif /* ACE_HAS_NEW_NOTHROW */37 38 #else /* ACE_NEW_THROWS_EXCEPTIONS */39 40 # define ACE_NEW_RETURN(POINTER,CONSTRUCTOR,RET_VAL) \41 do { POINTER = new CONSTRUCTOR; \42 if (POINTER == 0) { errno = ENOMEM; return RET_VAL; } \43 } while (0)44 # define ACE_NEW(POINTER,CONSTRUCTOR) \45 do { POINTER = new CONSTRUCTOR; \46 if (POINTER == 0) { errno = ENOMEM; return; } \47 } while (0)48 # define ACE_NEW_NORETURN(POINTER,CONSTRUCTOR) \49 do { POINTER = new CONSTRUCTOR; \50 if (POINTER == 0) { errno = ENOMEM; } \51 } while (0)52 #endif
使用时:
1 ACE_Thread_Descriptor *thr_desc = 0;2 ACE_NEW_RETURN (thr_desc,3 ACE_Thread_Descriptor,4 -1);