先看一个例子:
/ 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!
只是返回 NULL, 没有导致整个程序终止.
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__));
在 文件/usr/include/c++/4.8/new里可以查到.
在 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