如何使用新运算符检查内存分配失败?

ist*_*dy0 26 c++ memory-management smart-pointers

就在最近,我将项目的语言切换为使用C++.使用C语言,我使用了malloc,然后检查malloc是否成功但是使用C++,我使用'new'来分配内存,我想知道你是怎么做的通常会检查内存分配失败.

从我的谷歌搜索,我看到如下所示.

char *buf = new (nothrow)char[10];
Run Code Online (Sandbox Code Playgroud)

我也看到了以下内容.

try{} catch(bad_alloc&) {}
Run Code Online (Sandbox Code Playgroud)

但是下面呢?我正在使用一些chrome库例程来使用智能指针.

例如,我有如下代码.

scoped_array<char> buf(new char[MAX_BUF]);
Run Code Online (Sandbox Code Playgroud)

使用智能指针很棒,但我不确定如何检查内存分配是否成功.我是否需要使用nothrow或try/catch分成两个单独的语句?你通常如何在C++中进行这些检查?

任何建议将被认真考虑.

Arm*_*yan 20

好吧,你打电话给新投掷bad_alloc,所以你必须抓住它:

try
{
    scoped_array<char> buf(new char[MAX_BUF]);
    ...
}
catch(std::bad_alloc&) 
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

要么

scoped_array<char> buf(new(nothrow) char[MAX_BUF]);
if(!buf)
{
   //allocation failed
}
Run Code Online (Sandbox Code Playgroud)

我的回答是,智能指针传播异常.因此,如果您使用普通的throw new分配内存,则必须捕获异常.如果您使用nothrow new分配,那么您必须检查nullptr.在任何情况下,智能指针都不会向此逻辑添加任何内容

  • 请注意,通常您不会将每个`new`包装在自己的`try`块中.相反,你可以在你的程序中的任何一点捕获,你可以有用地做一些事情. (5认同)

Jer*_*fin 16

我不想这么说,但是IMO,你的方向是错误的(不幸的是,你得到的其他答案也没有真正指向正确的方向).

而不同品种的智能指针和/或正常与不抛出的变体之间做出选择new,你应该很可能至少需要两个步骤,从你在做什么回去,收藏更换您手动管理动态数据结构.这可能并不总是正确的选择,但至少在我的经验,这是去一个正确的方式很多,往往不是.标准库有许多可能性(矢量,双端队列,列表,集合等),很有可能你可以使用其中一个,而不是直接与new公司打交道.

默认情况下,这些将使用最终使用正常(抛出)变体的分配器new.因此,您通常希望将大多数代码放在一个try相当高级别的块中,并且有一个catch处理内存耗尽的子句.

当/如果你确实需要直接处理内存分配时,你仍然希望提供类似于库中标准容器的接口,这样它就可以使用常规算法和迭代器.使用现有容器的初始体验将在您达到这一点时付出相当的效果,即使这可能是未来的发展方向.


Jar*_*Par 6

在C++中,有两种主要方式可以new分配内存,每种方法都需要不同的错误检查.

标准new运算符将std::bad_alloc在失败时抛出异常,这可以像正常异常一样处理

try {
  char* c = new char[100];
} catch (std::bad_alloc&) {
  // Handle error
}
Run Code Online (Sandbox Code Playgroud)

或者替代nothrow版本new只会NULL在失败时返回

char* c = new (std::nothrow) char[100];
if (!c) {
  // Handle error
}
Run Code Online (Sandbox Code Playgroud)

我很好奇,但是当分配失败时你期望做什么?如果没有可用于分配对象的内存,那么在此过程中通常可以做的很少.