Domanda

    

Questa domanda ha già una risposta qui:

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

Ho provato a cogliere l'eccezione in questo modo ma non funziona, nessun aiuto?

È stato utile?

Soluzione

Non esiste alcuna cosa come " null pointer exception " in C ++. Le uniche eccezioni che puoi rilevare sono le eccezioni espressamente generate dalle espressioni throw (più, come notato da Pavel, alcune eccezioni C ++ standard generate intrinsecamente dall'operatore standard new , dynamic_cast ecc.). Non ci sono altre eccezioni in C ++. Dereferenziare puntatori null, divisione per zero ecc. Non genera eccezioni in C ++, produce comportamento indefinito . Se desideri generare eccezioni in casi del genere, è tua responsabilità rilevare manualmente queste condizioni e fare lanciare in modo esplicito. Funziona così in C ++.

Qualsiasi altra cosa sembri cercare non ha niente a che fare con il linguaggio C ++, ma piuttosto una caratteristica di particolare implementazione. In Visual C ++, ad esempio, le eccezioni di sistema / hardware possono essere "convertite" nelle eccezioni C ++, ma c'è un prezzo associato a questa funzionalità non standard, che normalmente non vale la pena pagare.

Altri suggerimenti

Non puoi. La de-referenziazione di un puntatore null è una cosa di sistema.

Su Linux, il sistema operativo genera segnali nell'applicazione. Dai un'occhiata a csignal per vedere come gestire i segnali. Per "catturare" uno, avresti agganciato una funzione che verrà chiamata nel caso di SIGSEGV . Qui puoi provare a stampare alcune informazioni prima di terminare con grazia il programma.

Windows utilizza gestione delle eccezioni strutturate . È possibile utilizzare le istruzioni __try / __ tranne , come indicato nel collegamento precedente. Il modo in cui l'ho fatto in una certa utility di debug che ho scritto è stato con la funzione _set_se_translator (perché corrisponde strettamente agli hook). In Visual Studio, assicurati di avere SEH abilitato. Con quella funzione, puoi agganciare una funzione da chiamare quando il sistema genera un'eccezione nella tua applicazione; nel tuo caso lo chiamerebbe con EXCEPTION_ACCESS_VIOLATION . Puoi quindi lanciare un'eccezione e farla propagare indietro come se fosse stata generata un'eccezione.

Dereferenziare un puntatore nullo (o un puntatore che si trova oltre la fine dell'array o un puntatore non valido casuale) provoca un comportamento indefinito. Non esiste un modo portatile per " catturare " che.

Esiste un modo molto semplice per rilevare qualsiasi tipo di eccezione (divisione per zero, violazione dell'accesso, ecc.) in Visual Studio utilizzando prova - > Blocchi catch (...) .

È sufficiente una modifica del progetto minore. Abilita l'opzione / EHa nelle impostazioni del progetto. Vedi Proprietà del progetto - > C / C ++ - > Generazione di codice - > Modifica Abilita eccezioni C ++ su " Sì con eccezioni SEH " . Questo è tutto!

Vedi i dettagli qui: http://msdn.microsoft.com/ it-it / library / 1deeycx5 (v = vs.80) aspx

C ++ non esegue il controllo del puntatore (anche se suppongo che alcune implementazioni potrebbero). Se si tenta di scrivere su un puntatore null, molto probabilmente si bloccherà in modo anomalo. Non genererà un'eccezione. Se vuoi coglierlo devi controllare tu stesso il valore del puntatore prima di provare a scrivergli.

Generalmente non puoi. Anche se tu potessi, sarebbe come provare a mettere un cerotto su un sottomarino che è sorto.

Un'applicazione paralizzata può fare molti più danni di una che si è schiantata. Il mio consiglio qui sarebbe di lasciarlo andare in crash, quindi di risolvere il motivo per cui si è bloccato. Risciacquare. Ripeti.

Come altri hanno già detto, non puoi farlo in C ++.

Se posso fare un punto più ampio: anche in una lingua che ti consente di catturarlo, l'azione migliore è quella di non toccare i puntatori nulli. Catturare un errore quando è già esploso in faccia, quindi decidere di andare avanti come se non fosse successo, non è una buona strategia di codifica. Cose come la dereferenza del puntatore null, overflow dello stack, ecc., Dovrebbero essere visti come eventi catastrofici ed evitati sulla difensiva, anche se il tuo linguaggio ti consente di reagire in modo diverso.

Non esiste un modo indipendente dalla piattaforma per farlo. In Windows / MSVC ++ puoi usare __try / __except

Ma non consiglierei di farlo comunque. Quasi certamente non puoi recuperare correttamente da un errore di segmentazione.

Se lo desideri, puoi semplicemente fare il puntatore controllandoti e lanciare ...

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

quindi ovviamente questo sarebbe solo per il debug del problema, il nullptr non dovrebbe verificarsi in primo luogo :)

Risposta breve: non è possibile in modo portatile o standard, perché bug come questo potenzialmente corrompono il processo stesso.

Risposta lunga: puoi fare più di quanto pensi, e sicuramente più del default del programma che si blocca. Tuttavia, devi tenere a mente 3 cose:
1) Questi bug sono PIÙ gravi delle eccezioni e spesso non possono presentarsi come eccezioni alla tua logica.
2) Il rilevamento e la gestione delle librerie dipenderà dalla piattaforma dal back-end, anche se è possibile fornire un'interfaccia pulita e astratta per il consumo pubblico.
3) Ci saranno sempre alcuni crash così gravi che non potrai nemmeno rilevarli prima della fine.

Fondamentalmente, guasti come segfaults o corruzione dell'heap non sono eccezioni perché stanno corrompendo il processo effettivo che esegue il programma. Tutto ciò che hai codificato nel programma fa parte del programma, inclusa la gestione delle eccezioni, quindi qualsiasi cosa oltre a registrare un bel messaggio di errore prima che il processo muoia è sconsigliabile nei pochi casi non è impossibile. In POSIX, il sistema operativo utilizza un sistema di segnalazione per segnalare errori come questi ed è possibile registrare le funzioni di richiamata per registrare quale era l'errore prima di uscire. In Windows, il sistema operativo a volte può convertirli in eccezioni di aspetto normale da cui è possibile acquisire e ripristinare.

Alla fine, tuttavia, la soluzione migliore è codificare in modo difensivo contro tali incubi. Su un dato sistema operativo ce ne saranno alcuni così male che non puoi rilevarli, anche in linea di principio, prima che il tuo processo muoia. Ad esempio, corrompere il proprio puntatore dello stack è qualcosa che può bloccarti così gravemente che nemmeno i callback del segnale POSIX non lo vedono mai.

In VC ++ 2013 (e anche nelle versioni precedenti) è possibile aggiungere punti di interruzione alle eccezioni:

  1. Premi Ctrl + Alt + Canc (questo aprirà la finestra di dialogo delle eccezioni).
  2. Espandi "Eccezioni Win32"
  3. Assicurati che " 0xC0000005 violazione di accesso " l'eccezione è selezionata.

Ora di nuovo il debug, un breakpoint verrà colpito esattamente quando si verifica la dereferenza nulla.

Non esiste alcuna eccezione per il puntatore NULL in c ++, ma vuoi comunque catturare lo stesso, quindi devi fornire la tua implementazione di classe per lo stesso.

sotto è l'esempio per lo stesso.

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

Ora basato sul controllo puntatore NULL, può essere lanciato come throw (Exception (" NullPointerException ", NULL)); e sotto è il codice per catturare lo stesso.

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

        cout<<"value="<<e.what()<< endl;
   }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top