Pregunta

    

Esta pregunta ya tiene una respuesta aquí:

         
  try {
        int* p = 0;
        *p = 1;
    } catch (...) {
        cout << "null pointer." << endl;
    }

Traté de detectar la excepción como esta pero no funciona, ¿alguna ayuda?

¿Fue útil?

Solución

No existe tal cosa como "excepción de puntero nulo" en C ++. Las únicas excepciones que puede detectar son las excepciones lanzadas explícitamente por las expresiones throw (además, como señaló Pavel, algunas excepciones C ++ estándar lanzadas intrínsecamente por el operador new estándar, dynamic_cast etc.) No hay otras excepciones en C ++. Desreferenciar punteros nulos, división por cero, etc. no genera excepciones en C ++, produce comportamiento indefinido . Si desea que se produzcan excepciones en casos como ese, es su responsabilidad detectar estas condiciones manualmente y hacer throw explícitamente. Así es como funciona en C ++.

Cualquier otra cosa que parezca estar buscando tiene que ver con el lenguaje C ++, sino más bien con una característica de implementación particular. En Visual C ++, por ejemplo, las excepciones de sistema / hardware se pueden "convertir". en excepciones de C ++, pero hay un precio asociado a esta funcionalidad no estándar, que normalmente no vale la pena pagar.

Otros consejos

No puedes. Desreferenciar un puntero nulo es algo del sistema.

En Linux, el sistema operativo genera señales en su aplicación. Eche un vistazo a csignal para ver cómo manejar las señales. Para '' atrapar '' uno, conectarías una función que se llamará en el caso de SIGSEGV . Aquí puede intentar imprimir alguna información antes de finalizar con gracia el programa.

Windows usa estructurado-manejo de excepciones . Puede usar la __try / __ instristics excepto , como se describe en el enlace anterior. La forma en que lo hice en una determinada utilidad de depuración que escribí fue con la función _set_se_translator (porque coincide estrechamente con los ganchos). En Visual Studio, asegúrese de tener SEH habilitado. Con esa función, puede conectar una función para llamar cuando el sistema genera una excepción en su aplicación; en su caso, lo llamaría con EXCEPTION_ACCESS_VIOLATION . Luego puede lanzar una excepción y hacer que se propague de nuevo como si se lanzara una excepción en primer lugar.

Anular la referencia a un valor nulo (o puntero que está más allá del final de la matriz, o un puntero no válido aleatorio) da como resultado un comportamiento indefinido. No hay una forma portátil de "atrapar" eso.

Hay una manera muy fácil de detectar cualquier tipo de excepción (división por cero, infracción de acceso, etc.) en Visual Studio usando try - > catch (...) bloques.

Un pequeño ajuste de proyecto es suficiente. Simplemente habilite la opción / EHa en la configuración del proyecto. Ver Propiedades del proyecto - > C / C ++ - > Generación de código - > Modifique Habilitar excepciones de C ++ a "Sí con excepciones de SEH" . ¡Eso es!

Ver detalles aquí: http://msdn.microsoft.com/ es-es / biblioteca / 1deeycx5 (v = vs.80) .aspx

C ++ no realiza la comprobación del puntero (aunque supongo que algunas implementaciones podrían hacerlo). Si intenta escribir en un puntero nulo, lo más probable es que se bloquee con fuerza. No arrojará una excepción. Si desea captar esto, debe verificar el valor del puntero usted mismo antes de intentar escribir en él.

Generalmente no puedes. Incluso si pudieras, sería como tratar de poner una tirita en un submarino que ha provocado una fuga.

Una aplicación paralizada puede causar mucho más daño que una que se ha bloqueado. Mi consejo aquí sería dejar que se bloquee y luego arreglar por qué se bloqueó. Enjuague. Repita.

Como han dicho otros, no puedes hacer esto en C ++.

Si puedo hacer un punto más amplio: incluso en un lenguaje que le permita captarlo, la mejor acción es no tocar punteros nulos. Detectar un error cuando ya está explotado en tu cara y luego decidir seguir adelante como si no hubiera sucedido, no es una buena estrategia de codificación. Cosas como la desreferencia de puntero nulo, desbordamiento de pila, etc., deben verse como eventos catastróficos y evitarse defensivamente, incluso si su lenguaje le permite reaccionar de manera diferente.

No hay una forma independiente de la plataforma para hacer esto. En Windows / MSVC ++ puede usar __try / __excepto

Pero no recomendaría hacerlo de todos modos. Es casi seguro que no puede recuperarse correctamente de una falla de segmentación.

Si quisieras, puedes hacer que el puntero te revise y lanzar ...

if (p == nullptr) throw std::exception("woot! a nullptr!")
p->foo();

así que, por supuesto, esto solo sería para depurar el problema, el nullptr no debería ocurrir en primer lugar :)

Respuesta corta: no puede hacerlo de forma portátil o estándar, porque errores como este están corrompiendo el proceso en sí mismo.

Respuesta larga: puedes hacer más de lo que piensas, y definitivamente más que el valor predeterminado del programa que simplemente falla. Sin embargo, debe tener 3 cosas en mente:
1) Estos errores son MÁS graves que las excepciones y, a menudo, no pueden presentarse como excepciones a su lógica.
2) Su detección y manejo de la biblioteca DE ellos dependerá de la plataforma en el back-end, a pesar de que puede proporcionar una interfaz abstracta limpia para el consumo público.
3) Siempre habrá algunos bloqueos que son tan malos que ni siquiera puedes detectarlos antes del final.

Básicamente, fallas como segfaults o corrupción de montón no son excepciones porque están corrompiendo el proceso real que ejecuta el programa. Todo lo que codificó en el programa es parte del programa, incluido el manejo de excepciones, por lo que cualquier cosa más allá de registrar un buen mensaje de error antes de que el proceso muera es desaconsejable en los pocos casos, no es imposible. En POSIX, el sistema operativo utiliza un sistema de señalización para informar fallas como estas, y puede registrar funciones de devolución de llamada para registrar cuál fue el error antes de salir. En Windows, el sistema operativo a veces puede convertirlos en excepciones de aspecto normal que puede detectar y recuperar.

Finalmente, sin embargo, su mejor opción es codificar defensivamente contra tales pesadillas. En cualquier sistema operativo dado, habrá algunos que son tan malos que no podrá detectarlos, incluso en principio, antes de que su proceso falle. Por ejemplo, corromper su propio puntero de pila es algo que puede bloquearlo tanto que incluso sus devoluciones de llamada de señal POSIX nunca lo ven.

En VC ++ 2013 (y también versiones anteriores) puede poner puntos de interrupción en las excepciones:

  1. Presione Ctrl + Alt + Supr (esto abrirá el cuadro de diálogo de excepción).
  2. Expandir 'Excepciones de Win32'
  3. Asegúrese de que " 0xC0000005 Infracción de acceso " la excepción está marcada.

Ahora vuelva a depurar, se alcanzará un punto de interrupción exactamente cuando ocurra la desreferencia nula.

No existe una excepción de puntero NULL en c ++ pero aún así desea capturar lo mismo, entonces debe proporcionar su propia implementación de clase para el mismo.

a continuación es el ejemplo de lo mismo.

class Exception {

public:
   Exception(const string& msg,int val) : msg_(msg),e(val) {}
  ~Exception( ) {}

   string getMessage( ) const {return(msg_);}
   int what(){ return e;}
private:
   string msg_;
   int e;
};

Ahora basado en la comprobación de puntero NULL, se puede lanzar como, throw (Exception (" NullPointerException ", NULL)); y debajo está el código para atrapar lo mismo.

 catch(Exception& e) {
      cout << "Not a valid object: " << e.getMessage( )<< ": ";

        cout<<"value="<<e.what()<< endl;
   }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top