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

发布于 2024-11-26 10:49:04 字数 533 浏览 3 评论 0原文

就在最近,我将项目语言从 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++ 中进行这些检查?

任何建议将不胜感激。

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.

From my google search, I saw nothrow like the following.

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.

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++?

Any advice will be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

寒冷纷飞旳雪 2024-12-03 10:49:04

好吧,你调用 new 会抛出 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
}

我的答案的意思是智能指针传播异常。因此,如果您使用普通的 throwing new 来分配内存,则必须捕获异常。如果您使用 nothrow new 进行分配,则必须检查 nullptr。无论如何,智能指针不会向此逻辑添加任何内容

Well, you call new that throws bad_alloc, so you must catch it:

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

街角迷惘 2024-12-03 10:49:04

我不想这么说,但在我看来,你走错了方向(不幸的是,你得到的其他答案也没有真正指出你正确的方向)。

您应该可能从您正在做的事情中至少后退两步,而不是在不同类型的智能指针和/或new的正常与无抛出变体之间进行选择,并用集合替换手动管理的动态数据结构。这可能并不总是正确的选择,但至少根据我的经验,这是经常使用的正确方法。标准库有多种可能性(向量、双端队列、列表、集合等),并且很有可能您可以使用其中之一,而不是直接处理 new 和 company 。

默认情况下,它们将使用一个分配器,该分配器最终使用operator new,并在失败时抛出异常。因此,您通常希望将大部分代码放在相当高级别的 try 块中,并使用一个 catch 子句来处理内存不足的情况1

当/如果您确实需要直接分配内存时,您很可能仍然希望提供一个类似于库中标准容器的接口,以便它可以与正常算法和迭代器一起使用。当您达到这一点时,您使用现有容器的初步经验将得到很好的回报,尽管这可能还有很长的路要走。


  1. 或不。例如,它在 Linux 下不一定有很多好处,Linux 经常使用称为 OOM-killer 的东西来应对内存不足的情况。在这种情况下,您将无法从分配失败中恢复。要么分配成功,要么进程被立即终止。

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).

Rather than choosing between different varieties of smart pointer and/or normal vs. nothrow variants of new, you should probably take at least two more steps back from what you're doing, and replace your manually-managed dynamic data structures with collections. This may not always be the right choice, but at least in my experience, it's the right way to go a lot more 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.

By default, those will use an allocator that ends up using operator new, and throwing in case of failure. 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 there1.

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.


  1. Or not. It won't necessarily do a lot of good under Linux, for example, which frequently reacts to out of memory situations with something called the OOM-killer. In this case, you won't be able to recover from allocation failure. Either the allocation will succeed, or the process summarily killed.
救星 2024-12-03 10:49:04

在 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
}

我很好奇当分配失败时你期望做什么?如果没有可用的内存来分配对象,则该过程中通常可以做的事情很少。

In C++ there are 2 primary ways in which new allocates memory and each requires different error checking.

The standard new operator will throw a std::bad_alloc exception on failure and this can be handled like a normal exception

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

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.

九八野马 2024-12-03 10:49:04

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

要么

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
}

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文