Esempio
int *ptr;
*ptr = 1000;
posso rilevare l'eccezione di violazione dell'accesso alla memoria utilizzando lo standard C ++ senza utilizzare alcuno specifico di Microsoft.
Esempio
int *ptr;
*ptr = 1000;
posso rilevare l'eccezione di violazione dell'accesso alla memoria utilizzando lo standard C ++ senza utilizzare alcuno specifico di Microsoft.
Risposte:
No. C ++ non genera un'eccezione quando si fa qualcosa di sbagliato, che incorrerebbe in un calo delle prestazioni. Cose come le violazioni di accesso o la divisione per zero errori sono più simili a eccezioni "macchina", piuttosto che cose a livello di linguaggio che puoi individuare.
Leggilo e piangi!
L'avevo capito. Se non lanci dal gestore, il gestore continuerà e così farà l'eccezione.
La magia accade quando lanci la tua eccezione e gestisci quella.
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <tchar.h>
void SignalHandler(int signal)
{
printf("Signal %d",signal);
throw "!Access Violation!";
}
int main()
{
typedef void (*SignalHandlerPointer)(int);
SignalHandlerPointer previousHandler;
previousHandler = signal(SIGSEGV , SignalHandler);
try{
*(int *) 0 = 0;// Baaaaaaad thing that should never be caught. You should write good code in the first place.
}
catch(char *e)
{
printf("Exception Caught: %s\n",e);
}
printf("Now we continue, unhindered, like the abomination never happened. (I am an EVIL genius)\n");
printf("But please kids, DONT TRY THIS AT HOME ;)\n");
}
sigaltstackinstallati stack di segnali alternativi ( ) (a meno che l'implementazione di svolgimento dell'eccezione C ++ non lo consenta) e ogni funzione di runtime che gestisce il meccanismo di svolgimento stesso dovrebbe essere a prova di segnale.
signal(SIGSEGV, SIG_DFL);
Esiste un modo molto semplice per rilevare qualsiasi tipo di eccezione (divisione per zero, violazione di accesso, ecc.) In Visual Studio utilizzando try -> catch (...) block. È sufficiente un piccolo ritocco delle impostazioni del progetto. Abilita semplicemente l'opzione / EHa nelle impostazioni del progetto. Vedere Proprietà progetto -> C / C ++ -> Generazione codice -> Modifica Abilita eccezioni C ++ su "Sì con eccezioni SEH" . Questo è tutto!
Vedi i dettagli qui: http://msdn.microsoft.com/en-us/library/1deeycx5(v=vs.80).aspx
Almeno per me, l' signal(SIGSEGV ...)approccio menzionato in un'altra risposta non ha funzionato su Win32 con Visual C ++ 2015 . Quello che ha funzionato per me è stato usare _set_se_translator()trovato in eh.h. Funziona così:
Passaggio 1 ) Assicurati di abilitare Sì con eccezioni SEH (/ EHa) in Proprietà progetto / C ++ / Generazione codice / Abilita eccezioni C ++ , come menzionato nella risposta di Volodymyr Frytskyy .
Passaggio 2 ) Chiama _set_se_translator(), passando un puntatore a funzione (o lambda) per il nuovo traduttore di eccezioni . Si chiama traduttore perché fondamentalmente prende solo l'eccezione di basso livello e la rilancia come qualcosa di più facile da catturare, come ad esempio std::exception:
#include <string>
#include <eh.h>
// Be sure to enable "Yes with SEH Exceptions (/EHa)" in C++ / Code Generation;
_set_se_translator([](unsigned int u, EXCEPTION_POINTERS *pExp) {
std::string error = "SE Exception: ";
switch (u) {
case 0xC0000005:
error += "Access Violation";
break;
default:
char result[11];
sprintf_s(result, 11, "0x%08X", u);
error += result;
};
throw std::exception(error.c_str());
});
Passaggio 3 ) Cattura l'eccezione come faresti normalmente:
try{
MakeAnException();
}
catch(std::exception ex){
HandleIt();
};
Questo tipo di situazione dipende dall'implementazione e di conseguenza richiederà un meccanismo specifico del fornitore per eseguire il trap. Con Microsoft questo coinvolgerà SEH e * nix implicherà un segnale
In generale, comunque l'intercettazione di un'eccezione di violazione di accesso è una molto cattiva idea. Non c'è quasi modo di recuperare da un'eccezione AV e il tentativo di farlo risulterà solo più difficile trovare bug nel tuo programma.
Come affermato, non esiste un modo non Microsoft / fornitore di compilatori per farlo sulla piattaforma Windows. Tuttavia, è ovviamente utile rilevare questi tipi di eccezioni nel normale modo try {} catch (exception ex) {} per la segnalazione degli errori e più un'uscita graziosa della tua app (come dice JaredPar, l'app ora è probabilmente nei guai) . Usiamo _se_translator_function in un semplice class wrapper che ci permette di catturare le seguenti eccezioni in un gestore try:
DECLARE_EXCEPTION_CLASS(datatype_misalignment)
DECLARE_EXCEPTION_CLASS(breakpoint)
DECLARE_EXCEPTION_CLASS(single_step)
DECLARE_EXCEPTION_CLASS(array_bounds_exceeded)
DECLARE_EXCEPTION_CLASS(flt_denormal_operand)
DECLARE_EXCEPTION_CLASS(flt_divide_by_zero)
DECLARE_EXCEPTION_CLASS(flt_inexact_result)
DECLARE_EXCEPTION_CLASS(flt_invalid_operation)
DECLARE_EXCEPTION_CLASS(flt_overflow)
DECLARE_EXCEPTION_CLASS(flt_stack_check)
DECLARE_EXCEPTION_CLASS(flt_underflow)
DECLARE_EXCEPTION_CLASS(int_divide_by_zero)
DECLARE_EXCEPTION_CLASS(int_overflow)
DECLARE_EXCEPTION_CLASS(priv_instruction)
DECLARE_EXCEPTION_CLASS(in_page_error)
DECLARE_EXCEPTION_CLASS(illegal_instruction)
DECLARE_EXCEPTION_CLASS(noncontinuable_exception)
DECLARE_EXCEPTION_CLASS(stack_overflow)
DECLARE_EXCEPTION_CLASS(invalid_disposition)
DECLARE_EXCEPTION_CLASS(guard_page)
DECLARE_EXCEPTION_CLASS(invalid_handle)
DECLARE_EXCEPTION_CLASS(microsoft_cpp)
La classe originale proviene da questo articolo molto utile:
Non il meccanismo di gestione delle eccezioni, ma puoi usare il meccanismo signal () fornito dal C.
> man signal
11 SIGSEGV create core image segmentation violation
Scrivere su un puntatore NULL probabilmente causerà un segnale SIGSEGV
signal()fa parte dello standard posix. Windows implementa lo standard posix (così come Linux e unix)
Una violazione del genere significa che c'è qualcosa di gravemente sbagliato nel codice ed è inaffidabile. Vedo che un programma potrebbe voler provare a salvare i dati dell'utente in un modo che si spera non sovrascriverà i dati precedenti, nella speranza che i dati dell'utente non siano già corrotti, ma per definizione non esiste un metodo standard di affrontare un comportamento indefinito.