当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《在任何情况下new都会返回NULL吗?》经验,为你挑选了3个好方法。

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



1> Michael Burr..:

在这方面,默认情况下VC6不合规.VC6的new返回0(或NULL).

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

在Visual C++中失败时,operator new不会抛出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_alloc使用std::nothrow参数进行投掷:

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

这似乎适用于VC6,因此它可能是一种或多或少机械地修复代码以便与所有编译器一起工作的方法,因此您不必重新编写现有的错误处理.


公平地说,VC6在批准C++标准之前就已经发布了,这也是它不符合规范的一个原因.确实标准在当时几乎已经完成,但是必须要记住,有一些开发周期,VC6可能至少在一年前开始.

2> 小智..:

我想补充一点(有点争议的)意见,即在分配尝试后检查NULL几乎是徒劳的一种练习.如果你的程序遇到这种情况,你可能做得比快速退出更多.任何后续分配尝试都很可能也会失败.

在不检查NULL的情况下,您的后续代码将尝试取消引用NULL指针,该指针倾向于快速退出程序,具有相对独特(且易于调试)的退出条件.

我不是试图告诉你检查NULL,它肯定是尽职尽责的编程.但是你从中获得的收益并不多,除非在非常特殊的情况下你可以存储一些恢复信息(不分配更多的内存),或者释放不那么重要的内存等等.但对于大多数人来说,这些情况相对较少.

鉴于此,我只是相信编译器会个人抛出bad_alloc - 至少在大多数情况下.


"代码完成"建议预分配可在运行到内存不足情况时使用的内存"安全网",以便在退出之前保存调试信息.
问题是,在现代VM系统上,如果你来到(虚拟)内存的任何地方_near_,那么事情就会分页太多,它将完全无法使用.
在某些情况下,您的操作系统将允许您分配内存,而无需真正映射新页面(延迟评估).但是当你去尝试使用那个内存时,没有什么可用的,并且进程被杀死了.便宜的硬盘和大型交换文件的问题少了......
我不敢苟同; 有时无法分配内存不是终端而且崩溃是不可取的.可能不需要处理每个数据,但如果跳过某些数据,则警告操作员很重要.并非每个人都有一个带磁盘备份的内存管理环境.
@sharptooth,@ Adam Hawes:你正在讨论分配内存是可选的情况 - 如果可以,你会用它做点什么.当然你需要检查NULL.在大多数情况下,内存是必不可少的,因此失败的分配意味着整体失败.
我认为重点是,如果内存不足,你可能没有足够的内存来做任何事情.

3> Brian R. Bon..:

基于C++规范,当你只使用没有params的普通new时,它总会抛出std :: bad_alloc,但当然可能会有一些不兼容的编译器.

我不会编码以符合非c ++兼容的编译器.VC6在这方面就是其中之一.

尽管在删除指针后始终将指针设置为NULL是一种很好的做法.因此,仍然需要检查NULL.

话虽如此,这里有几个清理代码的选项:

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

清理代码的一种安全方法是首先调用:set_new_handler.

然后你可以检查你的处理程序中的NULL并在返回NULL时抛出std :: bad_alloc.

如果你更喜欢异常,那么这是你最好的选择.如果你想更好地返回NULL,那么你也可以通过在新处理程序中执行catch来实现.

选项2:使用重载的新

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];

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

推荐阅读
落单鸟人
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有