Frage

    

Diese Frage bereits eine Antwort hier:

    
            
  •              Fangen Zugriffsverletzung Ausnahmen?                                      8 Antworten                          
  •     
    
  try {
        int* p = 0;
        *p = 1;
    } catch (...) {
        cout << "null pointer." << endl;
    }

Ich habe versucht, die Ausnahme wie diese zu fangen, aber es funktioniert nicht, jede mögliche Hilfe?

War es hilfreich?

Lösung

Es gibt nicht so etwas wie „Null-Zeiger-Ausnahme“ in C ++. Die einzigen Ausnahmen Sie fangen können, sind die Ausnahmen ausdrücklich von throw Ausdrücke geworfen (plus, wie Pavel erwähnte, einige Standard-C ++ Ausnahmen intrinsisch durch Standard operator new geworfen, dynamic_cast usw.). Es gibt keine andere Ausnahmen in C ++. Dereferencing Null-Zeiger, Division durch Null usw. erzeugt keine Ausnahmen in C ++, produziert es nicht definiertes Verhalten . Wenn Sie Ausnahmen in Fällen wie geworfen wollen, dass es in Ihrer eigenen Verantwortung ist es, manuell diese Bedingungen zu erkennen und zu tun explizit throw. Das ist, wie es funktioniert in C ++.

Wie auch immer, was Sie scheinen zu suchen hat unter Hinweis darauf, mit C ++ Sprache zu tun, sondern eher ein Merkmal von bestimmten Implementierung. In Visual C ++ zum Beispiel System / Hardware-Ausnahmen können „umgewandelt“ in C ++ Ausnahmen geben, aber es gibt einen Preis zu dieser Nicht-Standard-Funktionalität angebracht, die die Zahlung normalerweise nicht wert ist.

Andere Tipps

Sie können nicht. De-Referenzierung ein Null-Zeiger ist ein System Sache.

Unter Linux das Betriebssystem stellt Signale in Ihrer Anwendung. Schauen Sie sich auf csignal zu sehen, wie Signale zu verarbeiten. Um „fangen“ ein, dann würden Sie eine Funktion, dass im Falle von SIGSEGV genannt wird einhaken. Hier können Sie versuchen, einige Informationen zu drucken, bevor Sie ordnungsgemäß das Programm beenden.

Windows verwendet structured-Ausnahmebehandlung . Sie können die instristics __try/__except verwenden, wie im vorherigen Link beschrieben. Die Art und Weise habe ich es in einem bestimmten Debug-Dienstprogramm, das ich schrieb mit der Funktion war _set_se_translator (weil es eng passt Haken). In Visual Studio, stellen Sie sicher, dass Sie SEH aktiviert. Mit dieser Funktion können Sie in einer Funktion Haken zu rufen, wenn das System eine Ausnahme in der Anwendung erhöht; in Ihrem Fall wäre es mit EXCEPTION_ACCESS_VIOLATION nennen. Sie können dann eine Ausnahme aus, und es hat propagieren zurück aus, als ob eine Ausnahme in erster Linie geworfen wurde.

Dereferenzierung einen Null (oder Zeiger, past-the-Ende des Arrays ist, oder ein zufälliger ungültiger Zeiger) führt zu undefiniertem Verhalten. Es gibt keine tragbare Art und Weise zu „fangen“ das.

Es gibt eine sehr einfache Möglichkeit, jede Art von Ausnahme (Division durch Null, Zugriffsverletzung, etc.) zu fangen in Visual Studio mit try -> catch (...) Blöcken.

Ein kleines Projekt Zwicken ist genug. Aktivieren Sie einfach die /EHa Option in Projekteinstellungen. Siehe Projekteigenschaften -> C / C ++ -> Code Generation -> Ändern der C ++ aktivieren Ausnahmen "Ja Mit SEH Ausnahmen" . Das ist es!

Weitere Details hier: http://msdn.microsoft.com/ en-us / library / 1deeycx5 (v = vs.80) aspx

C ++ nicht Zeiger Prüfung tun (obwohl ich einige Implementierungen annehmen könnte). Wenn Sie versuchen, auf einen Null-Zeiger zu schreiben ist es sehr wahrscheinlich, hart geht zum Absturz bringen. Es wird nicht eine Ausnahme werfen. Wenn Sie diese fangen wollen, müssen Sie den Wert des Zeigers selbst überprüfen, bevor Sie versuchen, es zu schreiben.

Im Allgemeinen kann man nicht. Auch wenn Sie könnte es wie der Versuch, ein Pflaster auf einem U-Boot sei zu setzen, die ein Leck hat.

Eine verkrüppelte Anwendung kann weit mehr Schaden anrichten als eine, die abgestürzt ist. Mein Rat wäre hier, lassen Sie es krachen dann beheben, warum es abgestürzt ist. Spülen. Wiederholen.

Wie schon andere gesagt haben, können Sie nicht tun dies in C ++.

Wenn ich einen weiteren Punkt machen: auch in einer Sprache, die Sie es fangen kann, ist die bessere Wirkung nicht Null-Zeiger zu berühren. Fangen einen Fehler, wenn es bereits in Ihrem Gesicht geblasen, dann nur auf die Entscheidung zu bewegen, wie es nicht passiert, ist keine gute Codierungsstrategie. Dinge wie Nullzeigerdereferenzierung, Stapelüberlauf usw. sollten als katastrophale Ereignisse und defensiv zu vermeiden, auch wenn Ihre Sprache ermöglicht es Ihnen, es anders zu reagieren, zu sehen.

Es gibt keine plattformunabhängige Art und Weise, dies zu tun. Unter Windows / MSVC ++ können Sie __try / __except

Aber ich würde nicht empfehlen, es trotzdem zu tun. Sie können an Sicherheit grenzender Wahrscheinlichkeit nicht korrekt von einem Segmentierungsfehler erholen.

Wenn Sie Sie wollte nur den Zeiger selbst überprüft tun könnte und werfen ...

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

so natürlich wäre dies nur das Problem zu debuggen, sollte das nullptr nicht in erster Linie auftreten:)

Kurze Antwort- Sie können nicht in einem tragbaren oder Standardweg, weil Fehler wie diese sind korrumpiert möglicherweise den Prozess selbst.

Long Antwort- Sie kann mehr tun, als Sie vielleicht denken, und auf jeden Fall mehr als der Standard des Programms Absturz nur. Allerdings müssen Sie 3 Dinge im Auge behalten:
1) Diese Fehler schwerer als Ausnahmen und kann oft nicht vorhanden als Ausnahmen von der Logik.
2) Ihre Erkennung und Bibliothek Umgang mit ihnen wird plattformabhängig am hinteren Ende, auch wenn Sie eine saubere abstrakte Schnittstelle für die Öffentlichkeit zur Verfügung stellen kann.
3) Es wird immer einige Abstürze, die so schlecht sind, können Sie sie vor dem Ende nicht einmal erkennen können.

Grundsätzlich Störungen wie segfaults oder Heapbeschädigung sind keine Ausnahmen, weil sie den eigentlichen Prozess sind korrumpiert das Programm ausgeführt wird. Alles, was Sie in das Programm codiert ist Teil des Programms, einschließlich der Ausnahmebehandlung, so etwas über eine schöne Fehlermeldung Anmeldung bevor der Prozess stirbt nicht ratsam in den wenigen Fällen ist es nicht unmöglich ist. In POSIX verwendet das O einen Signalisierungssystemfehler wie diese zu melden, und Sie können Callback-Funktionen registrieren anmelden, was der Fehler vor dem Beenden war. In Windows kann das OS manchmal sie in normal aussehende Ausnahmen umwandeln, die Sie fangen können und erholen sich von.

Letztlich aber Ihre beste Wette ist defensiv gegen solche Alpträume zu codieren. An jedem beliebigen Betriebssystem gibt es einige, die so schlecht sind, dass man sie nicht erkennen kann, auch im Prinzip vor Ihrem Prozess stirbt. Zum Beispiel ist Ihren eigenen Stapelzeiger korrumpiert etwas, das Sie so schlecht, dass sogar Ihre POSIX Signal Rückrufe sehen es zum Absturz bringen kann nie.

In VC ++ 2013 (und auch ältere Versionen) Sie können Haltepunkte auf Ausnahmen setzen:

  1. Drücken Sie Strg + Alt + Entf (das wird die Ausnahme-Dialog geöffnet).
  2. Öffnen 'Win32 Ausnahmen'
  3. Stellen Sie sicher, dass "0xC0000005 Zugriffsverletzung" Ausnahme aktiviert ist.

Nun wieder zu debuggen, wird ein Haltepunkt genau getroffen werden, wenn die die Null-Dereference passiert ist.

Es gibt keine NULL-Zeiger-Ausnahme in c ++ existiert aber immer noch wollen Sie das gleiche fangen, dann müssen Sie Ihre eigene Klasse Implementierung für denselben schaffen.

unten ist das Beispiel für das gleiche.

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

Jetzt basierend auf NULL-Zeiger überprüfen kann es wie warf werden, throw(Exception("NullPointerException",NULL)); und unten ist der Code das gleiche für den Fang.

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

        cout<<"value="<<e.what()<< endl;
   }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top