puede alguien por favor decirme cómo coger fuera de la excepción de memoria?

de ex.

try
{
    while(true)
    {
        int i = new int;
    }
}
catch( ? <--- what should be put here?)
{
    //exception handling
}

y también este,

queue<int> q;
try
{
     while(true)
     {
          q.push(10);
     }
}
catch( ? <---- what should be put here?)
{
     //error handling
}
InformationsquelleAutor in His Steps | 2011-10-13

4 Comentarios

  1. 49

    Captura std::bad_alloc.

    Usted también necesitará una estrategia para el manejo de los errores, ya que muchas de las cosas que te gustaría hacer requerirá de memoria (incluso si es sólo para mostrar un error al usuario antes de cerrar). Una estrategia es asignar un bloque de memoria en el inicio, y delete en el controlador de excepciones antes de intentar utilizar más memoria, por lo que hay algunos disponibles para su uso.

    • Gracias!! funciona
    • Tenga en cuenta que en situaciones prácticas de memoria ya han sido liberados por el desenredo de pila (destrucción de locales std::string variables de instancia) entre lanzar y atrapar el error. Normalmente un controlador para std::bad_alloc será bastante «en el exterior» del programa, mientras que la memoria podría quedarse profundamente anidadas situación. Sólo para decir que algo como imprimir un mensaje de error no tener fallar.
  2. 18

    Como otros han señalado, lo que quiere coger es std::bad_alloc. También puede utilizar catch(...) o catch(exception& ex) para capturar cualquier excepción; el segundo permite la excepción de los datos para ser leído y utilizado en el controlador de excepciones.

    Marca de Rescate ya había señalado que, cuando el programa no puede asignar más memoria, incluso imprimir un mensaje de error puede fallar. Considere el siguiente programa:

    #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
    }

    (Recomiendo fuertemente que el programa se compila como de 32 bits para evitar que se ejecute el sistema de memoria en una máquina de 64 bits. Los programas de 32 bits no puede asignar más de 4 GB de memoria, o 2 GB por defecto en Windows.)

    Cuando la primera bad_alloc se tira en el infinito while bucle, el control pasa a la catch bloque, pero el programa todavía se produce una excepción no controlada. Por qué? Otro bad_alloc se produce en el interior del controlador de excepción mientras tratando de imprimir a cerr. Usted puede verificar esto mediante el uso de un depurador: Establecer un punto de interrupción en la catch(bad_alloc& ex) línea, ejecutar el programa en el depurador, luego paso a través de cada instrucción una vez que alcance el punto de ruptura. Un bad_alloc excepción será lanzada en el cerr declaración.

    Como tal, para manejar adecuadamente un fuera-de-memoria escenario, es necesario dejar de lado algo de memoria, de modo que usted puede imprimir un mensaje de error antes de salir. De lo contrario, el programa se bloqueará sólo en una excepción no controlada, mientras que tratando de imprimir el mensaje de error. Para ello, se puede asignar un bloque de memoria que se cancela la asignación en el controlador de excepciones, como Marca de Rescate sugerido:

    //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);
    }
    //...
    • Nunca ha oído hablar de RAII? Si estás haciendo la ingeniería de software como este, no es necesario el uso de C++ — puede utilizar C.
    • He visto gente que dice, que el «truco» de pre-asignación de memoria lleva a nunca ejecución de la posibilidad de obtener una condición de memoria.
    • Y ¿por qué iba a coger std::bad_alloc como un valor?
    • Actualizado el código para capturar la excepción por referencia. Sin embargo, este código propósito evita RAII porque está específicamente destinado a la memoria de la fuga con fines de demostración. Que es el punto entero de la respuesta.
  3. 14
    catch (std::bad_alloc& ba){
        cerr << "bad_alloc caught: " << ba.what() << endl;
    }

    Como una nota usted debe leer bdonlan del comentario. La llamada a cerr bien puede fracasar. Marca de Rescate de la sugerencia en su respuesta, es una buena estrategia para mitigar este problema.

    • Nota: la impresión de Que a cerr puede fallar debido a la condición de memoria.
    • Estoy de acuerdo con usted allí. Yo no considerar esa situación, estoy demasiado acostumbrado a que el problema se produce cuando intento asignar obscenamente grandes vectores ;). He actualizado mi respuesta.
    • hm? ¿Cómo actualizar tu respuesta?
    • Muy lentamente después me comentó 😛
  4. 5

    Debe catch un objeto de tipo std::bad_alloc.

    Alternativamente, también puede utilizar un nothrow verison de new como:

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

    Cuando se utiliza esta, no es la excepción se produce si el new falla. En su lugar,simplemente devuelve NULL que comprobar antes de continuar.

    • Puedo de alguna manera nothrow versión de nuevo como predeterminado, así que no necesito escribir (nothrow) cada vez?
    • No sé si eso es posible. Tal vez, como último recurso, usted puede hacer esto : #define NEW new (nothrow) y, a continuación,int *pi = NEW int[N];.
    • Creo que nunca he utilizado esta forma de nuevo como en mi código, el éxito de la asignación de la memoria no es opcional.

Dejar respuesta

Please enter your comment!
Please enter your name here