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

发布于 2024-12-09 17:19:40 字数 385 浏览 0 评论 0原文

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

例如。

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
}

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
}

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

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

发布评论

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

评论(4

信愁 2024-12-16 17:19:40

捕获 std::bad_alloc

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

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 before attempting to use more memory, so that there is some available to use.

谜兔 2024-12-16 17:19:40

正如其他人所指出的,您想要捕获的是 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 的内存,或者Windows 上默认为 2 GB。

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

因此,为了正确处理内存不足的情况,您需要留出一些内存,以便可以在退出之前打印错误消息。否则,程序在尝试打印错误消息时将因未处理的异常而崩溃。为此,您可以分配一块在异常处理程序中释放的内存块,如 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);
}
//...

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.

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:

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

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 handler while 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.

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:

// 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);
}
//...
儭儭莪哋寶赑 2024-12-16 17:19:40
catch (std::bad_alloc& ba){
    cerr << "bad_alloc caught: " << ba.what() << endl;
}

作为注释,您应该阅读 bdonlan 的评论。对 cerr 的调用很可能会失败。马克·兰塞姆(Mark Ransom)在回答中的建议是缓解这个问题的好策略。

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.

人疚 2024-12-16 17:19:40

您应该catch一个std::bad_alloc类型的对象。

或者,您还可以使用 newnothrow 版本:

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

当您使用此版本时,如果 new 失败,则不会引发异常。相反,它只是返回 NULL,您需要在继续操作之前检查该值。

You should catch an object of type std::bad_alloc.

Alternatively, you can also use a nothrow verison of new as:

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.

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