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