1,检查new是否失败通常没多大意义
1993年前,c++一直要求在内存分配失败时operator new要返回0,现在则是要求operator new抛出std::bad_alloc异常。很多c++程序是在编译器开始支持新规范前写的。c++标准委员会不想放弃那些已有的遵循返回0规范的代 码,所以他们提供了另外形式的operator new(以及operator new[])以继续提供返回0功能。这些 形式被称为"无抛出",因为他们没用过一个throw,而是在使用new的入口点采用了nothrow对象:
class widget { ... };
widget *pw1 = new widget ; // 分配失败抛出 std::bad_alloc if
if (pw1 == 0) ... // 这个检查一定失败
widget *pw2 = new (nothrow ) widget ; // 若分配失败返回
if (pw2 == 0) ... // 这个检查可能会成功
不管是用"正规"(即抛出异常)形式的new还是"无抛出"形式的new,重要的是你必须为内存分配失败做好准备。最简单的方法是使用 set_new_handler,因为它对两种形式都有用。
// new_set_new_handler.cpp
// compile with: /EHsc
#include
#include
using namespace std ;
void __cdecl newhandler ( )
{
cout << "The new_handler is called:" << endl ;
throw bad_alloc ( );
return ;
}
int main ( )
{
set_new_handler (newhandler );
try
{
while ( 1 )
{
int *p = new int [5000000];
if (p == NULL )
{
cout << "Memory use out!" << endl ; // 这条语句永远不会被执行 !
exit (0);
}
cout << "Allocating 5000000 ints." << endl ;
}
}
catch ( exception e )
{
cout << e .what ( ) << " xxx" << endl ;
}
}
如果你的应用申请不到内存的情况下,还能继续运行,那就用nothrow。
如果你的应用申请不到内存的情况下,就不能继续运行,那就直接挂。另外,cerr 可能会向stderr写一些错误提示,而有些C++ lib中默认对bad_alloc的处理,就是调用cerr输出一些信息然后exit,对某些在stderr上重新打开了其它文件的应用来说,这可能造成大问题,所以必须自己处理bad_alloc
2, delete p; p = NULL;
删除一个已经删除的指针,会出现程序崩溃,是不允许的!
因为 delete p; 后,系统回收空间前 p 是个可访问的地址 。
多次delete一个NULL指针则没有问题。
int main ( )
{
int *p = new int ();
delete p ;
p = NULL ; // 不赋值为 NULL, 再次 delete 会导致 crash
delete p ;
}