[英]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
類型的對象。
或者,您也可以使用new
的nothrow
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.