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

时间:2011-07-26 16:10:29

标签: c++ memory-management smart-pointers

就在最近,我将我的项目语言转换为使用C ++中的C ++。 使用C,我使用了malloc,之后我检查malloc是否成功但是使用C ++,我使用'new'来分配内存,我想知道你通常如何检查内存分配失败。

从我的谷歌搜索中,我看到了以下内容。

char *buf = new (nothrow)char[10];

我也看到了以下内容。

try{} catch(bad_alloc&) {}

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

例如,我的代码如下。

scoped_array<char> buf(new char[MAX_BUF]);

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

任何建议都将受到赞赏。

4 个答案:

答案 0 :(得分:20)

好吧,你打电话给那个引发bad_alloc的新人,所以你必须抓住它:

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

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

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

答案 1 :(得分:16)

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

不是在new的不同种类的智能指针和/或正常与非正式变体之间进行选择,而是可能从你正在做的事情中至少再做两步,并使用集合替换您手动管理的动态数据结构。这可能总是是正确的选择,但至少根据我的经验,这是经常去批次的正确方法。标准库有许多可能性(向量,双端队列,列表,集等),很有可能你可以使用其中一个,而不是直接与new和公司打交道。

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

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

答案 2 :(得分:6)

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

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

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

或者替代nothrownew只会在失败时返回NULL

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

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

答案 3 :(得分:1)

您仍需要检查内存分配失败。

要么

scoped_array<char> buf;

try {
  buf.reset( new char[MAX_BUF] );
} catch( std::bad_alloc& ) {
  // Handle the failure
}

或者

scoped_array<char> buf( new(std::nothrow)char[MAX_BUF] );

if( buf.get() == NULL ) {
   // Handle the failure
}