让new返回NULL的方法是什么?
我记得好像通过设置编译参数就可以指定new失败时不throw而是返回NULL,不用在new的时候明确指定。是什么?
[解决办法]
1.6 异常
现在,我们把这些new/delete和异常结合起来。再次考虑这条语句:
B *p = new D;
当其调用new操作而没有分配到足够内存时将发生什么?
在C++的黑暗年代(1994年及以前),对大部分编译器而言,new操作将返回NULL。这曾经是对C的malloc函数的合理扩展。幸运的是,我们现在生活在光明的年代,编译器强大了,类被设计得很漂亮,而编译运行库的new操作会抛异常了。
前面,我展示了在 <new> 中出现的8个函数的申明。那时,我做了些小手脚;这里是它们的完整形式:
namespace std
{
class bad_alloc
{
// ...
};
}
//
// new and delete
//
void *operator new(std::size_t) throw(std::bad_alloc);
void operator delete(void *) throw();
//
// array new and delete
//
void *operator new[](std::size_t) throw(std::bad_alloc);
void operator delete[](void *) throw();
//
// placement new and delete
//
void *operator new(std::size_t, void *) throw();
void operator delete(void *, void *) throw();
//
// placement array new and delete
//
void *operator new[](std::size_t, void *) throw();
void operator delete[](void *, void *) throw();
在这些new操作族中,只有非placement形式的会抛异常(std::bad_alloc)。这个异常意味着内存耗尽状态,或其它内存分配失败。你可能奇怪为什么placement形式不抛异常;但记住,这些函数实际上根本不分配任何内存,所以它们没有分配问题可报告。
没有delete操作抛异常。这不奇怪,因为delete不分配新内存,只是将旧内存还回去。
1.7 异常消除
相对于会抛异常的new操作形式, <new> 中也申明了不抛异常的重载版本:
namespace std
{
struct nothrow_t
{
// ...
};
extern const nothrow_t nothrow;
}
//
// new and delete
//
void *operator new(std::size_t, std::nothrow_t const &) throw();
void operator delete(void *, std::nothrow_t const &) throw();
//
// array new and delete
//
void *operator new[](std::size_t, std::nothrow_t const &) throw();
void operator delete[](void *, std::nothrow_t const &) throw();
这几个函数也被认为是new操作和delete操作的placement形式,因为它们也接收额外参数。和前面的控制对象分配位置的版本不同,这几个只是让你分辨出抛异常的new和不抛异常的new。
#include <iostream>
#include <new>
using namespace std;
int main()
{
int *p;
//
// 'new ' that can throw
//
try
{
p = new int;
}
catch(bad_alloc &)
{
cout < < " 'new ' threw an exception ";
}
//
// 'new ' that can 't throw
//
try
{
p = new(nothrow) int;
}
catch(bad_alloc &)
{
cout < < "this line should never appear ";
}
//
return 0;
}
注意两个new表达式的重要不同之处:
p = new int;
在分配失败时抛std::bad_alloc,而
p = new(nothrow) int;
在分配失败时不抛异常,它返回NULL(就象malloc和C++黑暗年代的new)。
如果你不喜欢nothrow的语法,或你的编译器不支持,你可以这样达到同样效果:
#include <new>
//
// function template emulating 'new(std::nothrow) '
//
template <typename T>
T *new_nothrow() throw()
{
T *p;
try
{
p = new T;
}
catch(std::bad_alloc &)
{
p = NULL;
}
return p;
}
//
// example usage
//
int main()
{
int *p = new_nothrow <int> (); // equivalent to 'new(nothrow) int '
return 0;
}
这个模板函数与它效仿的new(nothrow)表达式同有一个潜在的异常安全漏洞。现在,我将它作为习题留给你去找出来。(恐怕没什么用的提示:和placement delete有关。)
[解决办法]
在windows、linux等任何一个保护模式下,发生内存不够都是个很困难很恐怖的事情了。
内存都光了,讨论new是抛异常还是返回null有啥意义呢。
[解决办法]
int * p = new ( nothrow )int;
其实在内存分配失败的时候我们能做的事情几乎没什么意义
具体参见herbsutter的exceptional c++ style。
[解决办法]
我记得好像通过设置编译参数就可以指定new失败时不throw而是返回NULL,不用在new的时候明确指定。是什么?
-------------------------------------------------
nothrow形式的new就是这个功能的。
[解决办法]
内存如果光了
你那个程序也不能return NULL
------------------------------------------
new因该是从堆里分配内存 return语句只与栈相关 new是否能成功分配内存 与是否能return没什么必然的联系吧 例如
void main(void)
{
try{
int * pbuf = new int[ver large];
}
catch(...)
{
return 0;
}
return 1;
}