Подтвердить что ты не робот

Как исключить из памяти исключение в С++?

Кто-нибудь может рассказать мне, как исключить из памяти исключение?

для ex.

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
}
4b9b3361

Ответ 1

Catch std::bad_alloc.

Вам также понадобится стратегия для обработки ошибок, так как многие из вещей, которые вы хотели бы сделать, потребуют памяти (даже если она только покажет ошибку пользователю перед выключением). Одна стратегия состоит в том, чтобы выделить блок памяти при запуске и delete в обработчике исключений, прежде чем пытаться использовать больше памяти, чтобы некоторые из них были доступны для использования.

Ответ 2

catch (std::bad_alloc& ba){
    cerr << "bad_alloc caught: " << ba.what() << endl;
}

В качестве примечания вы должны прочитать комментарий bdonlan. Вызов cerr может сильно потерпеть неудачу. Предложение Марка Рэнсом в его ответе - хорошая стратегия для смягчения этой проблемы.

Ответ 3

Как отмечали другие, вы хотите поймать std::bad_alloc. Вы также можете использовать catch(...) или catch(exception& ex), чтобы поймать любое исключение; последний позволяет данные исключений считываться и использоваться в обработчике исключений.

Марк Рэнсом уже указывал, что когда программа не может выделить больше памяти, даже печать сообщения об ошибке может завершиться неудачей. Рассмотрим следующую программу:
#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 ГБ памяти или по 2 ГБ по умолчанию Windows).

Когда первый bad_alloc получает бросок в бесконечном цикле while, управление передается блоку catch, но программа по-прежнему не работает с необработанным исключением. Зачем? Другой bad_alloc забрасывается внутри обработчика исключений при попытке печати на cerr. Вы можете проверить это с помощью отладчика: установите точку останова в строке catch(bad_alloc ex), запустите программу в отладчике, затем выполните каждую инструкцию после достижения точки останова. Исключение bad_alloc будет выбрано в инструкции cerr.

Таким образом, чтобы правильно обрабатывать сценарий с отсутствием памяти, вам нужно выделить некоторую память, чтобы вы могли распечатать сообщение об ошибке перед выходом. В противном случае программа просто выйдет из строя при необработанном исключении, пытаясь распечатать сообщение об ошибке. Для этого вы можете выделить блок памяти, который освобождается в обработчике исключений, как предложил Марк Рэнсом:

// 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);
}
//...

Ответ 4

Вы должны catch объект типа std::bad_alloc.

В качестве альтернативы вы также можете использовать nothrow verison new как:

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

Когда вы используете это, никакое исключение не возникает, если new терпит неудачу. Вместо этого он просто возвращает NULL, который вы проверяете, прежде чем продолжить.