在任何情况下new都将返回NULL?

我知道,根据C ++标准,万一新的分配内存失败,应该抛出std :: bad_alloc异常。 但是我听说有些编译器,例如VC6(或CRT实现?)不遵守它。 这是真的 ? 我之所以这样问是因为在每条新语句之后检查NULL会使代码看起来非常难看。

3个解决方案
56 votes

在这方面,默认情况下VC6不兼容。 VC6的new返回了0(或std::bad_alloc)。

这是有关此问题的Microsoft知识库文章,以及使用自定义new处理程序的建议解决方法:

  • 新操作符不会在Visual C ++中失败时引发bad_alloc异常

如果您有针对VC6行为编写的旧代码,则可以通过链接到名为new704的目标文件来使用较新的MSVC编译器(例如7.0及更高版本)获得相同的行为。7.0和2000中实际上有一组相当复杂的规则。 7.1编译器(VS2002和VS2003)确定它们默认为非抛出还是抛出0

似乎MS在8.0(VS2005)中已将其清除—现在,除非您专门链接到new,否则它始终默认为抛出新异常。

请注意,您可以指定您希望new返回0,而不是使用std::nothrow参数抛出std::bad_alloc

SomeType *p = new(std::nothrow) SomeType;

这似乎在VC6中有效,因此它可能是一种或多或少地机械地修复代码以使其与所有编译器相同的方式,因此您不必重新处理现有的错误处理。

Michael Burr answered 2020-01-14T15:52:02Z
19 votes

我想补充一下(有点争议),认为分配尝试后检查NULL几乎是徒劳的。 如果您的程序遇到了这种情况,那么您可能除了快速退出之外别无所求。 任何后续的分配尝试也很可能也会失败。

在不检查NULL的情况下,您的后续代码将尝试取消引用NULL指针,这往往会以相对独特(且易于调试)的退出条件快速退出程序。

我并不是想让您摆脱对NULL的检查,这肯定是出于认真的编程。 但是您不能从中获得很多收益,除非在非常特殊的情况下,您可以存储一些恢复信息(而不分配更多的内存),或者释放不那么重要的内存,等等。但是对于大多数人来说,这些情况相对较少。

鉴于此,至少在大多数情况下,我相信编译器会亲自抛出bad_alloc。

answered 2020-01-14T15:52:36Z
9 votes

基于C ++规范,当您仅使用不带参数的普通新函数时,它将始终抛出std :: bad_alloc,但是当然可以存在一些不兼容的编译器。

我不会编码为与非c ++兼容的编译器兼容。 VC6在这方面就是其中之一。

最好将指针删除后再将其设置为NULL。 因此,因此仍然需要检查NULL。

话虽这么说,以下是清理代码的几种选择:

选项1:设置自己的新处理程序

清理代码的安全方法是先调用:set_new_handler。

然后,您可以在处理程序中检查NULL,如果返回NULL,则将std :: bad_alloc扔在那里。

如果您更喜欢例外,那么这是您的最佳选择。 如果您希望更好地返回NULL,那么也可以通过在新处理程序内执行catch来实现。

选项2:使用重载的new

C ++标准头文件定义了一个空的struct nothrow。 您可以在new内部使用此结构的对象来获取其重载版本,该版本始终返回NULL。

void* operator new (size_t size, const std::nothrow_t &);
void* operator new[] (void *v, const std::nothrow_t &nt);

因此,在您的代码中:

 char *p = new(std::nothrow) char[1024];

这是进一步阅读的良好参考

Brian R. Bondy answered 2020-01-14T15:53:45Z
translate from https://stackoverflow.com:/questions/550451/will-new-return-null-in-any-case