根据C++ reference,您可以通过以下方式新建一个对象:
MyClass * p1 = new MyClass;
或
MyClass * p2 = new (std::nothrow) MyClass;
第二个将返回空指针而不是抛出异常。
但是,根据我的经验,我几乎看不到这个版本。
例如Google建议不要在代码中使用异常,但我们可以看到他们没有在Chromium中使用nothrow版本。
有没有理由我们更喜欢默认的一个而不是一个?即使在没有使用异常的项目中也是如此?
- 编辑 -
跟进问题:我应该检查malloc()
的返回值吗?
看起来,相反,许多人建议检查malloc的返回值,有人说是因为:
许多分配失败与内存不足无关。碎片可能会导致分配失败,因为即使有足够的内存空间,也没有足够的连续空间可供使用。
这是真的吗?在这种情况下,为什么我们会以不同的方式对待malloc()
和new()
?
答案 0 :(得分:30)
但是,根据我的经验,我几乎看不到这个版本。
如果您可以在本地处理故障,您可以使用它(或等效地,从默认版本中捕获异常);也许通过请求释放一些其他内存然后重试,或者尝试分配更小的内容,或使用不需要额外内存的替代算法。
是否有任何理由我们更喜欢默认的一个而不是一个?
例外的一般原则:如果你不能在本地处理它,那么在本地检查是没有意义的。与返回值不同,异常不能被忽略,因此无论使用空指针还是使用空指针都不可能进行耕作。
即使在没有使用例外的项目中也是如此?
通常,根本无法处理内存不足的情况。在这种情况下,终止程序可能是最好的回应;这是对未处理异常的默认响应。因此,即使您没有使用例外,默认new
也许是大多数情况下的最佳选择。
我应该检查
malloc()
的返回值吗?
是的:这是检查它是否成功的唯一方法。如果不这样做,那么最终可能会使用空指针,给出未定义的行为:通常是崩溃,但可能是数据损坏或其他奇怪的行为以及长时间的调试会话(希望)找出问题所在。
为什么我们会在这种情况下区别对待
malloc()
和new
?
因为malloc
强制我们检查返回值,而new
为我们提供了更少侵入式错误处理的选项。
答案 1 :(得分:5)
如果您使用投掷版本,则无需测试每个new
调用的结果,以查看它是成功还是失败。通常在许多/大多数应用程序中,如果您的分配失败,您无法做很多事情,只需退出/中止,如果您没有明确尝试/ catch,则会自动为您执行此操作。
如果你使用nothrow
版本,你最终可能会在你的应用程序中传播一个空指针,然后在显然与内存分配完全无关的点上崩溃/退出MUCH,从而使调试变得更加困难。