Question

    

Cette question a déjà une réponse ici:

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

J'ai essayé de capturer l'exception de cette manière mais cela ne fonctionne pas, aucune aide?

Était-ce utile?

La solution

Il n'y a rien de tel que "l'exception de pointeur null". en C ++. Les seules exceptions que vous pouvez détecter sont les exceptions explicitement émises par les expressions throw (plus, comme Pavel l'a noté, certaines exceptions C ++ standard émises intrinsèquement par l'opérateur standard new , dynamic_cast etc). Il n'y a pas d'autres exceptions en C ++. Le déréférencement des pointeurs nuls, la division par zéro, etc. ne génère pas d'exceptions en C ++, il génère un comportement non défini . Si vous souhaitez que des exceptions soient générées dans de tels cas, il vous incombe de détecter manuellement ces conditions et de renvoyer de manière explicite. Voilà comment cela fonctionne en C ++.

Tout ce que vous semblez rechercher semble ne pas concerner le langage C ++, mais plutôt une fonctionnalité d’implémentation particulière. Dans Visual C ++, par exemple, les exceptions système / matériel peuvent être "converties". des exceptions en C ++, mais cette fonctionnalité non standard n'est pas rentable.

Autres conseils

Vous ne pouvez pas. Dé-référencer un pointeur nul est une chose système.

Sous Linux, le système d'exploitation génère des signaux dans votre application. Consultez csignal pour savoir comment gérer les signaux. Pour " attraper " Premièrement, vous utiliseriez une fonction qui sera appelée dans le cas de SIGSEGV . Ici, vous pouvez essayer d’imprimer certaines informations avant de mettre fin au programme gracieusement.

Windows utilise la gestion des exceptions structurées . Vous pouvez utiliser la syntaxe __ try / __ except , comme indiqué dans le lien précédent. La façon dont je l'ai fait dans un certain utilitaire de débogage que j'ai écrit était avec la fonction _set_se_translator (car il correspond étroitement aux points d'ancrage). Dans Visual Studio, assurez-vous que SEH est activé. Avec cette fonction, vous pouvez connecter une fonction à appeler lorsque le système déclenche une exception dans votre application. dans votre cas, il l’appellerait avec EXCEPTION_ACCESS_VIOLATION . Vous pouvez ensuite lancer une exception et la faire se reproduire comme si une exception avait été lancée.

Le déréférencement d'un null (ou d'un pointeur situé au-delà de l'extrémité du tableau, ou d'un pointeur incorrect incorrect) entraîne un comportement non défini. Il n'y a pas de moyen portable pour "attraper" ça.

Il existe un moyen très simple d'attraper tout type d'exception (division par zéro, violation d'accès, etc.) dans Visual Studio à l'aide de try - > catch (...) bloque.

Un petit projet suffit. Activez simplement l'option / EHa dans les paramètres du projet. Voir Propriétés du projet - > C / C ++ - > Génération de code - > Modifiez l'option Activer les exceptions C ++ en "Oui avec les exceptions SEH" . C'est ça!

Voir les détails ici: http://msdn.microsoft.com/ en-us / library / 1deeycx5 (v = vs.80) .aspx

C ++ ne vérifie pas le pointeur (bien que je suppose que certaines implémentations le pourraient). Si vous essayez d'écrire sur un pointeur NULL, il risque fort de planter. Il ne lancera pas une exception. Si vous voulez intercepter cela, vous devez vérifier vous-même la valeur du pointeur avant d'essayer d'y écrire.

En général, vous ne pouvez pas. Même si vous le pouviez, ce serait comme essayer de poser un pansement sur un sous-marin qui a provoqué une fuite.

Une application endommagée peut faire beaucoup plus de dégâts que celle qui est tombée en panne. Mon conseil ici serait de le laisser planter puis de déterminer pourquoi il s'est écrasé. Rincer. Répétez.

Comme d'autres l'ont déjà dit, vous ne pouvez pas le faire en C ++.

Si je peux faire valoir un point plus large: même dans un langage qui vous permet de l'attraper, la meilleure chose à faire est de ne pas toucher les pointeurs nuls. Détecter une erreur quand elle est déjà éclatée, puis décider de continuer comme si de rien n'était, n'est pas une bonne stratégie de codage. Des éléments tels que la déréférence du pointeur null, le débordement de pile, etc., doivent être considérés comme des événements catastrophiques et évités de manière défensive, même si votre langage vous permet de réagir différemment.

Il n’existe aucun moyen indépendant de la plate-forme de le faire. Sous Windows / MSVC ++, vous pouvez utiliser __try / __ excepté

Mais je ne recommanderais pas de le faire de toute façon. Il est presque certainement impossible de remédier correctement à une erreur de segmentation.

Si vous le vouliez, vous pouvez simplement vérifier le pointeur et lancer ...

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

Bien sûr, ce ne serait que pour résoudre le problème, le nullptr ne devrait pas se produire en premier lieu:)

Réponse courte: vous ne pouvez pas le faire de manière portable ou standard, car de tels bogues risquent de corrompre le processus lui-même.

Réponse longue: vous pouvez faire plus que vous ne le pensez, et bien plus que le défaut du programme qui tombe en panne. Cependant, vous devez garder à l’esprit 3 choses:
1) Ces bugs sont PLUS graves que les exceptions et ne peuvent souvent pas être présentés comme des exceptions à votre logique.
2) Votre détection et votre gestion de bibliothèque dépendront de la plate-forme, même si vous pouvez fournir une interface abstraite vierge pour la consommation publique.
3) Il y aura toujours des accidents tellement graves que vous ne pourrez même pas les détecter avant la fin.

En gros, les erreurs telles que les erreurs de segmentation ou la corruption de tas ne sont pas des exceptions, car elles corrompent le processus réel exécutant le programme. Tout ce que vous avez codé dans le programme fait partie du programme, y compris la gestion des exceptions. Par conséquent, tout ce qui est au-delà de la consignation d'un message d'erreur intéressant avant la fin du processus est déconseillé dans les rares cas où cela n'est pas impossible. Sous POSIX, le système d'exploitation utilise un système de signalisation pour signaler les erreurs de ce type et vous pouvez enregistrer des fonctions de rappel pour consigner la nature de l'erreur avant de quitter. Sous Windows, le système d'exploitation peut parfois les convertir en exceptions d'apparence normale que vous pouvez détecter et récupérer.

En fin de compte, cependant, votre meilleur choix est de coder de manière défensive contre de tels cauchemars. Sur un système d'exploitation donné, certains seront si graves que vous ne pourrez pas les détecter, même en principe, avant la mort de votre processus. Par exemple, corrompre votre propre pointeur de pile peut vous bloquer tellement que même vos rappels de signal POSIX ne le voient jamais.

Dans VC ++ 2013 (et les versions précédentes également), vous pouvez placer des points d'arrêt sur les exceptions:

  1. Appuyez sur Ctrl + Alt + Suppr (cela ouvrira la boîte de dialogue des exceptions).
  2. Développez "Exceptions Win32"
  3. Assurez-vous que " 0xC0000005 Violation d'accès " l'exception est cochée.

Maintenant, recommencez le débogage, un point d'arrêt sera atteint exactement lorsque la déréférence NULL est survenue.

Il n’existe pas d’exception de pointeur NULL dans c ++, mais vous souhaitez tout de même saisir la même chose, vous devez donc fournir votre propre implémentation de classe.

ci-dessous est l'exemple pour le même.

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

Maintenant, sur la base du pointeur NULL, il peut être jeté comme, throw (Exception (" NullPointerException ", NULL)); et ci-dessous est le code pour attraper le même.

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

        cout<<"value="<<e.what()<< endl;
   }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top