先看一个例子:
/ nothrow example #include <iostream> // std::cout #include <new> // std::nothrow int main () { char* p = new char [0xffffffff]; if (p==0) std::cout << "Failed!\n"; else { std::cout << "Succeeded!\n"; delete[] p; } return 0; }执行:
charles@taotao:~/work$ ./testnew terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc Aborted (core dumped)我们希望 new能够项 malloc那样,如果不成功,返回NULL,而不是把整个程序挂掉.
这种情况下,可以用另外的一种形式的 new:
// nothrow example #include <iostream> // std::cout #include <new> // std::nothrow int main () { char* p = new(std::nothrow) char [0xffffffff]; if (p==0) std::cout << "Failed!\n"; else { std::cout << "Succeeded!\n"; delete[] p; } return 0; }然后,编译,执行:
charles@taotao:~/work$ ./testnew Failed!
GLIBC里面有对 new和delete两类重载函数的声明:
namespae std { extern const nothrow_t nothrow; } void* operator new(std::size_t) _GLIBCXX_THROW (std::bad_alloc) __attribute__((__externally_visible__)); void* operator new[](std::size_t) _GLIBCXX_THROW (std::bad_alloc) __attribute__((__externally_visible__)); void operator delete(void*) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void operator delete[](void*) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void* operator new(std::size_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void* operator new[](std::size_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void operator delete(void*, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void operator delete[](void*, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__));
在 http://www.cplusplus.com/reference/new/nothrow/
有对参数 std::nothrow_t的说明:
This constant value is used as an argument for operator new and operator new[] to indicate that these functions shall not throw an exception on failure, but return a null pointer instead.
By default, when the new
operator is used to attempt to allocate memory and the handling function is unable to do so, a bad_alloc exception is thrown. But when nothrow is used as argument for new
, it returns a null pointer instead.
This constant (nothrow) is just a value of type nothrow_t, with the only purpose of triggering an overloaded version of the function operator new (or operator new[]) that takes an argument of this type.
我们也可以写自己的 new和delete函数.
void * operator new(std::size_t size) throw(std::bad_alloc) { void *p = malloc(size); printf("my new is called!!\n"); return p; } void * operator new(std::size_t size, const std::nothrow_t & nothrow) { void *p = malloc(size); printf("ny new(nothrow) is called\n"); return p; } void operator delete(void *p) throw() { free(p); printf("my delete is called\n"); } void operator delete(void *p, std::nothrow_t ¬hrow) { free(p); printf("my delete(nothrow) is called\n"); }
int main () { char* p = new (std::nothrow) char; if (p==0) std::cout << "Failed!\n"; else { std::cout << "Succeeded!\n"; delete p; } return 0; }编译之后,执行:
charles@taotao:~/work$ ./testnew ny new(nothrow) is called Succeeded! my delete is called