in *_*eps 38 c++ exception try-catch
任何人都可以告诉我如何捕获内存异常?
对于前
try
{
while(true)
{
int i = new int;
}
}
catch( ? <--- what should be put here?)
{
//exception handling
}
Run Code Online (Sandbox Code Playgroud)
还有这个,
queue<int> q;
try
{
while(true)
{
q.push(10);
}
}
catch( ? <---- what should be put here?)
{
//error handling
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*som 50
您还需要一个处理错误的策略,因为您要做的许多事情都需要内存(即使它只是在关闭之前向用户显示错误).一种策略是在启动时分配一块内存,并在尝试使用更多内存之前delete在异常处理程序中分配一块内存,以便有一些可用.
bwD*_*aco 19
正如其他人所说,你想要抓住的是std::bad_alloc.您还可以使用catch(...)或catch(exception& ex)捕获任何异常; 后者允许在异常处理程序中读取和使用异常数据.
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
}
Run Code Online (Sandbox Code Playgroud)
(我强烈建议将程序编译为32位,以避免在64位计算机上运行系统内存.32位程序无法分配超过4 GB的内存,或Windows上默认为2 GB.)
当第一个bad_alloc被抛入无限while循环时,控制被传递给catch块,但程序仍然失败并带有未处理的异常.为什么?在尝试打印时,另一个在异常处理程序中bad_alloc抛出.您可以使用调试器对此进行验证:在该行设置断点,在调试器中运行该程序,然后在到达断点后逐步执行每个语句.一个例外将在抛出的语句.cerrcatch(bad_alloc& ex)bad_alloccerr
因此,要正确处理内存不足的情况,您需要预留一些内存,以便在退出之前打印错误消息.否则,程序将在尝试打印错误消息时在未处理的异常上崩溃.为此,您可以分配在异常处理程序中释放的内存块,正如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);
}
//...
Run Code Online (Sandbox Code Playgroud)
GWW*_*GWW 14
catch (std::bad_alloc& ba){
cerr << "bad_alloc caught: " << ba.what() << endl;
}
Run Code Online (Sandbox Code Playgroud)
作为一个注释你应该阅读bdonlan的评论.呼吁cerr很可能会失败.Mark Ransom在他的回答中提出了一个缓解这个问题的好策略.
你应该catch是一个类型的对象std::bad_alloc.
或者,您也可以使用以下nothrow版本new:
int *pi = new (nothrow) int[N];
if(pi == NULL)
{
std::cout << "Could not allocate memory" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
使用它时,如果new失败则不会抛出异常.相反,它只是返回NULL你检查的内容,然后再继续.