簡體   English   中英

如何在c ++中捕獲內存不足?

[英]how to catch out of memory exception in c++?

任何人都可以告訴我如何捕獲內存不足異常?

對於前

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
}

抓住std::bad_alloc

您還需要一個處理錯誤的策略,因為您要做的許多事情都需要內存(即使它只是在關閉之前向用戶顯示錯誤)。 一種策略是在啟動時分配一塊內存,並嘗試使用更多內存之前在異常處理程序中將其delete ,以便有一些可用。

正如其他人所說,你想要捕獲的是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);
}
//...
catch (std::bad_alloc& ba){
    cerr << "bad_alloc caught: " << ba.what() << endl;
}

作為一個注釋你應該閱讀bdonlan的評論。 cerr的調用很可能會失敗。 Mark Ransom在他的回答中提出了一個緩解這個問題的好策略。

您應該catch std::bad_alloc類型的對象。

或者,您也可以使用newnothrow verison作為:

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

使用它時,如果new失敗,則不會拋出異常。 相反,它只返回您檢查的NULL ,然后再繼續。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM