new失败的处理方法
常常会见到这样的代码:
int *p=new int;
if(p!=0)
{
return -1;
}
实际上,现在new失败的处理方法是抛出bad_alloc()异常,所以上述代码实际上不会执行到return -1;的部分,new失败不会将指针置空。
正确处理方式应该是这样:
- 1、new之后catch异常:
int main()
{
const int size=10*1024*1024;
for (int i=0;;++i)
{
cout<<i<<endl;
try
{
auto p=new char[size];
}
catch(const bad_alloc&e)
{
cout<<"bad alloc"<<endl;
break;
}
}
cout<<"end"<<endl;
getchar();
return 0;
}
结果如下:
程序在new失败之后抛出异常,捕获异常之后正常退出,没有发生崩溃等现象。
- 2、使用set_new_handler,异常之后会先调用这个函数,函数里边可以提示用户啥的,也不会直接崩溃:
void new_handle()
{
cerr<<"bad alloc"<<endl;
getchar();
exit(1);
}
int main()
{
set_new_handler(new_handle);
const int size=10*1024*1024;
for (int i=0;;++i)
{
cout<<i<<endl;
auto p=new char[size];
}
cout<<"end"<<endl;
getchar();
return 0;
}
结果如下:
- 3、使用std::nothrow处理,这时new失败的话不抛出bad_alloc异常,而是将指针置0,那么检测指针为0处理即可:
int main()
{
const int size=10*1024*1024;
for (int i=0;;++i)
{
cout<<i<<endl;
auto p=new(std::nothrow) char[size];
if(p==0)
{
cerr<<"bad alloc"<<endl;
break;
}
}
cout<<"end"<<endl;
getchar();
return 0;
}
结果如下:
小结
- 1、旧编译器new依然返回0标志着失败,但是很多编译器已经以异常处理的处理了
- 2、异常处理方法比较麻烦
- 3、set_new_handler处理比较好
- 4、std::nothrow每次new都需要写std::nothrow也比较麻烦
- 5、实际上new失败的情况是比较少见的,大部分情况不需要处理,不然太麻烦,但是对要求较高的代码还是应该仔细处理,然后是对申请大内存的代码也应当做处理