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
how to catch out of memory exception in c++?
提问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
.
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 delete
it 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_alloc
gets thrown in the infinite while
loop, control is passed to the catch
block, but the program still fails with an unhandled exception. Why? Another bad_alloc
is 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_alloc
exception will be thrown in the cerr
statement.
当第一个bad_alloc
在无限while
循环中被抛出时,控制被传递给catch
块,但程序仍然失败并出现未处理的异常。为什么?另一个在尝试打印时在异常处理程序中bad_alloc
抛出。您可以使用调试器来验证这一点:在该行设置断点,在调试器中运行程序,然后在到达断点后逐步执行每个语句。一个例外将在抛出的语句。cerr
catch(bad_alloc& ex)
bad_alloc
cerr
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 cerr
may 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 catch
an object of type std::bad_alloc
.
你应该catch
是一个类型的对象std::bad_alloc
。
Alternatively, you can also use a nothrow
verison of new
as:
或者,您也可以使用以下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 new
fails. Instead,it simply returns NULL
which you check before proceeding further.
当您使用它时,如果new
失败则不会抛出异常。相反,它只是返回NULL
您在进一步进行之前检查的内容。