猿问

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

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



慕沐林林
浏览 701回答 3
3回答

蓝山帝景

在这方面,默认情况下VC6不兼容。VC6的new返回0(或NULL)。这是有关此问题的Microsoft知识库文章,以及使用自定义new处理程序的建议解决方法:新操作符不会在Visual C ++中失败时引发bad_alloc异常如果您有针对VC6行为编写的旧代码,则可以通过链接名为的目标文件,使用较新的MSVC编译器(如7.0及更高版本)来获得相同的行为nothrownew.obj。在7.0和7.1编译器(VS2002和VS2003)中,实际上存在一组相当复杂的规则,以确定它们默认是非抛出还是抛出new。似乎MS在8.0(VS2005)中已将其清除 —现在,除非您专门链接到,否则它始终默认为抛出新异常nothrownew.obj。请注意,您可以使用参数指定要new返回0而不是抛出:std::bad_allocstd::nothrowSomeType *p = new(std::nothrow) SomeType;这似乎在VC6中有效,因此它可能是一种或多或少地机械修复代码以使其与所有编译器相同的方式,因此您不必重新处理现有的错误处理。

慕运维8079593

基于C ++规范,当您仅使用没有参数的普通新函数时,它将始终抛出std :: bad_alloc,但是当然可能会有一些不兼容的编译器。我不会编码为与非c ++兼容的编译器兼容。VC6在这方面就是其中之一。最好将指针删除后再将其设置为NULL。因此,因此仍然需要检查NULL。话虽这么说,以下是清理代码的几种选择:选项1:设置自己的新处理程序清理代码的安全方法是先调用:set_new_handler。然后,您可以在处理程序中检查NULL,如果返回NULL,则将std :: bad_alloc扔在那里。如果您更喜欢例外,那么这是您的最佳选择。如果您希望更好地返回NULL,那么也可以通过在新处理程序内执行catch来实现。选项2:使用重载的newC ++标准头文件定义了一个空的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];
随时随地看视频慕课网APP
我要回答