C++ 如何在c ++中捕获内存不足异常?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7749066/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 17:25:43  来源:igfitidea点击:

how to catch out of memory exception in c++?

c++exceptiontry-catch

提问by in His Steps

can anyone please tell me how to catch out of memory exception?

谁能告诉我如何捕捉内存不足的异常?

for ex.

例如。

try
{
    while(true)
    {
        int i = new int;
    }
}
catch( ? <--- what should be put here?)
{
    //exception handling
}

and also this,

还有这个,

queue<int> q;
try
{
     while(true)
     {
          q.push(10);
     }
}
catch( ? <---- what should be put here?)
{
     //error handling
}

回答by Mark Ransom

Catch std::bad_alloc.

赶上std::bad_alloc

You will also need a strategy for handling the errors, since many of the things you'd like to do will require memory (even if it's only to display an error to the user before shutting down). One strategy is to allocate a block of memory at startup, and deleteit in the exception handler beforeattempting to use more memory, so that there is some available to use.

您还需要一个处理错误的策略,因为您想做的许多事情都需要内存(即使只是在关闭之前向用户显示错误)。一种策略是在启动时分配一块内存,并尝试使用更多内存之前delete它在异常处理程序中,以便有一些可用。

回答by bwDraco

As others have noted, what you want to catch is std::bad_alloc. You can also use catch(...)or catch(exception& ex)to catch any exception; the latter allows the exception data to be read and used in the exception handler.

正如其他人所指出的,您想要捕获的是std::bad_alloc. 您还可以使用catch(...)catch(exception& ex)来捕获任何异常;后者允许在异常处理程序中读取和使用异常数据。

Mark Ransom had already pointed out that when the program cannot allocate any more memory, even printing an error message may fail. Consider the following program:

Mark Ransom 已经指出,当程序无法分配更多内存时,即使打印错误消息也可能失败。考虑以下程序:

#include <iostream>

using namespace std;

int main() {
    unsigned long long i = 0;
    try {
        while(true) {
            // Leaks memory on each iteration as there is no matching delete
            int* a = new int;
            i++;
        }
    } catch(bad_alloc& ex) {
        cerr << sizeof(int) * i << " bytes: Out of memory!";
        cin.get();
        exit(1);
    }

    return 0; // Unreachable
}

(I strongly recommend that the program be compiled as 32-bit to avoid running the system out of memory on a 64-bit machine. 32-bit programs cannot allocate more than 4 GB of memory, or 2 GB by default on Windows.)

我强烈建议将程序编译为 32 位,以避免在 64 位机器上运行系统内存不足。32 位程序不能分配超过 4 GB 的内存,或在 Windows 上默认为 2 GB。

When the first bad_allocgets thrown in the infinite whileloop, control is passed to the catchblock, but the program still fails with an unhandled exception. Why? Another bad_allocis thrown inside the exception handlerwhile trying to print to cerr. You can verify this by using a debugger: Set a breakpoint at the catch(bad_alloc& ex)line, run the program in the debugger, then step through each statement once you reach the breakpoint. A bad_allocexception will be thrown in the cerrstatement.

当第一个bad_alloc在无限while循环中被抛出时,控制被传递给catch块,但程序仍然失败并出现未处理的异常。为什么?另一个在尝试打印时在异常处理程序中bad_alloc抛出。您可以使用调试器来验证这一点:在该行设置断点,在调试器中运行程序,然后在到达断点后逐步执行每个语句。一个例外将在抛出的语句。cerrcatch(bad_alloc& ex)bad_alloccerr

As such, to properly handle an out-of-memory scenario, you need to set aside some memory so that you can print an error message before exiting. Otherwise, the program will just crash on an unhandled exception while trying to print the error message. To do so, you can allocate a block of memory that is deallocated in the exception handler, as Mark Ransom suggested:

因此,要正确处理内存不足的情况,您需要留出一些内存,以便在退出前打印错误消息。否则,程序将在尝试打印错误消息时因未处理的异常而崩溃。为此,您可以分配在异常处理程序中释放的内存块,正如 Mark Ransom 建议的那样:

// Reserve 16K of memory that can be deleted just in case we run out of memory
char* _emergencyMemory = new char[16384];
// ...
try {
// ...
} catch(bad_alloc& ex) {
    // Delete the reserved memory so we can print an error message before exiting
    delete[] _emergencyMemory;

    cerr << sizeof(int) * i << " bytes: Out of memory!";
    cin.get();
    exit(1);
}
//...

回答by GWW

catch (std::bad_alloc& ba){
    cerr << "bad_alloc caught: " << ba.what() << endl;
}

As a note you should read bdonlan's comment. The call to cerrmay very well fail. Mark Ransom's suggestion in his answer is a good strategy to mitigate this issue.

作为说明,您应该阅读 bdonlan 的评论。调用cerr很可能会失败。Mark Ransom 在他的回答中的建议是缓解这个问题的好策略。

回答by Nawaz

You should catchan object of type std::bad_alloc.

你应该catch是一个类型的对象std::bad_alloc

Alternatively, you can also use a nothrowverison of newas:

或者,您也可以使用以下nothrow版本new

int *pi = new (nothrow) int[N]; 
if(pi == NULL) 
{
   std::cout << "Could not allocate memory" << std::endl;
}

When you use this, no exception is thrown if the newfails. Instead,it simply returns NULLwhich you check before proceeding further.

当您使用它时,如果new失败则不会抛出异常。相反,它只是返回NULL您在进一步进行之前检查的内容。