C++ 如何使用 new 运算符检查内存分配失败?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6833143/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to check memory allocation failures with new operator?
提问by istudy0
Just recently I switched the language of my project to use C++ from C. With C, I used malloc and after that I check if malloc was successful but with C++, I use 'new' to allocate memory and I would like to know how you would normally check the memory allocation failure.
就在最近,我将项目的语言从 C 切换为使用 C++。对于 C,我使用了 malloc,然后我检查 malloc 是否成功,但是对于 C++,我使用“new”来分配内存,我想知道你如何通常会检查内存分配失败。
From my google search, I saw nothrow like the following.
从我的谷歌搜索中,我看到了如下所示的 nothrow。
char *buf = new (nothrow)char[10];
I also saw the following.
我还看到了以下内容。
try{} catch(bad_alloc&) {}
But what about the following? I am using some of chrome library routines to use smart pointers.
但是下面的呢?我正在使用一些 chrome 库例程来使用智能指针。
For instance, I have the code as follows.
例如,我的代码如下。
scoped_array<char> buf(new char[MAX_BUF]);
It is great to use smart pointers but I am just not sure how I should check if the memory allocation was successful. Do I need to break into two separate statement with nothrow or try/catch? How do you normally do these checks in C++?
使用智能指针很棒,但我不确定应该如何检查内存分配是否成功。我需要用 nothrow 或 try/catch 分成两个单独的语句吗?你通常如何在 C++ 中进行这些检查?
Any advice will be appreciated.
任何建议将被认真考虑。
采纳答案by Armen Tsirunyan
Well, you call new that throws bad_alloc
, so you must catch it:
好吧,你调用了 throws 的 new bad_alloc
,所以你必须抓住它:
try
{
scoped_array<char> buf(new char[MAX_BUF]);
...
}
catch(std::bad_alloc&)
{
...
}
or
或者
scoped_array<char> buf(new(nothrow) char[MAX_BUF]);
if(!buf)
{
//allocation failed
}
What I mean by my answer is that smart pointers propagate exceptions. So if you're allocating memory with ordinary throwing new, you must catch an exception. If you're allocating with a nothrow new, then you must check for nullptr
. In any case, smart pointers don't add anything to this logic
我的回答的意思是智能指针传播异常。因此,如果您使用普通的 throw new 分配内存,则必须捕获异常。如果您使用 nothrow new 进行分配,则必须检查nullptr
. 在任何情况下,智能指针都不会向此逻辑添加任何内容
回答by Jerry Coffin
I hate to say it, but IMO, you're going in the wrong direction (and, unfortunately, the other answers you've gotten haven't really pointed you in the right direction either).
我不想这么说,但是 IMO,你走错了方向(不幸的是,你得到的其他答案也没有真正指出你正确的方向)。
Rather than choosing between different varieties of smart pointer and/or normal vs. nothrow variants of new
, you should probablytake at least two more steps back from what you're doing, and replace your manually-managed dynamic data structures with collections. This may not alwaysbe the right choice, but at least in my experience, it's the right way to go a lotmore often than not. The standard library has a number of possibilities (vector, deque, list, set, etc.), and chances are pretty good that you can use one of them rather than dealing directly with new
and company at all.
与其在不同种类的智能指针和/或普通与 nothrow 变体之间进行选择new
,您可能应该从您正在做的事情中至少再退两步,并用集合替换手动管理的动态数据结构。这可能并不总是正确的选择,但至少在我的经验,这是去一个正确的方式很多,往往不是。标准库有多种可能性(向量、双端队列、列表、集合等),而且很有可能您可以使用其中之一,而不是直接与new
公司打交道。
By default, those will use an allocator that ends up using the normal (throwing) variant of new
. You, therefore, normally want to put most code in a try
block at a fairly high level, and have a catch
clause that deals with having run out of memory there.
默认情况下,这些将使用一个分配器,该分配器最终使用new
. 因此,您通常希望将大部分代码放在一个try
较高级别的块中,并有一个catch
子句处理那里的内存不足。
When/if you do need to deal with allocating memory directly, chances are pretty good that you still want to provide an interface similar to that of the standard containers in the library so it'll work with the normal algorithms and iterators. Your initial experience using the existing containers will pay of well when you get to this point, even though it may be a ways down the road.
当/如果您确实需要直接处理分配内存的问题,很有可能您仍然希望提供一个类似于库中标准容器的接口,以便它可以与普通算法和迭代器一起使用。当您到达这一点时,您使用现有容器的初步经验将得到很好的回报,即使它可能还有很长的路要走。
回答by JaredPar
In C++ there are 2 primary ways in which new
allocates memory and each requires different error checking.
在 C++ 中有两种主要的new
内存分配方式,每种方式都需要不同的错误检查。
The standard new
operator will throw a std::bad_alloc
exception on failure and this can be handled like a normal exception
标准new
操作符会std::bad_alloc
在失败时抛出异常,这可以像普通异常一样处理
try {
char* c = new char[100];
} catch (std::bad_alloc&) {
// Handle error
}
Or alternative the nothrow
version of new
will simply return NULL
on failure
或者替代nothrow
版本new
将简单地NULL
在失败时返回
char* c = new (std::nothrow) char[100];
if (!c) {
// Handle error
}
I'm curious though as to what you expect to do when the allocation fails? If there is no memory available to allocate your object, there's often very little which can be done in the process.
我很好奇当分配失败时你期望做什么?如果没有可用于分配对象的内存,则在此过程中通常可以完成的工作很少。
回答by Praetorian
You'll still need to check for a memory allocation failure.
您仍然需要检查内存分配失败。
Either
任何一个
scoped_array<char> buf;
try {
buf.reset( new char[MAX_BUF] );
} catch( std::bad_alloc& ) {
// Handle the failure
}
Or
或者
scoped_array<char> buf( new(std::nothrow)char[MAX_BUF] );
if( buf.get() == NULL ) {
// Handle the failure
}