就在最近,我将我的项目语言转换为使用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 ++进行这些检查?
任何建议都将受到赞赏。
答案 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
}
或者替代nothrow
版new
只会在失败时返回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
}