Auflösen von out of range-Problemen



  • Stichwort Debugger, eine nichtgefangene Exception landet im Call Stack normalerweise an der Stelle wo sie geworfen wird...

    (Kennt heutzutage eigentlich kaum noch jemand Debugger?)



  • Berndoni schrieb:

    Wie teste ich denn am Besten, ob die Startposition gültig ist?

    Indem du sie vorher mit der Länge des Strings vergleichst.

    if (startPos > deinString.length()) {
       // FEHLER! Tot und Verderben
    }
    else {
        // OK.
        deinString.erase(startPos, endPos);
    }
    


  • Um beim gdb die Ursache einer Exception festzustellen, benutzt man am besten den Befehl "catch throw". Damit läßt jede geworfene Exception das Programm anhalten.



  • Kann man mit Hilfe von Exceptions oder anderer Hilfsmittel auch Endlosschleifen verhindern?



  • wenn du hingehst und eine exception wirfst, wenn die bedingung, welche eine endlosschleife produzieren würde, könntest du dies vermeiden. Von der Verwendung des Konzept der Exceptions als Strukturbefehlen (Schleifen, etc.) ist aber abzuraten



  • HumeSikkins schrieb:

    Berndoni schrieb:

    Wie teste ich denn am Besten, ob die Startposition gültig ist?

    Indem du sie vorher mit der Länge des Strings vergleichst.

    if (startPos > deinString.length()) {
       // FEHLER! Tot und Verderben
    }
    else {
        // OK.
        deinString.erase(startPos, endPos);
    }
    

    Bei startPos == deinString.length() ist auch noch Tod und Verderben.



  • Was nutzt ihr denn für Hilfsmittel gegen Endlosschleifen?
    Oder verlasst ihr euch nur auf eure Erfahrung?



  • Man muss einfach nur garantieren, dass es eine Abbruchbedingung gibt.



  • Michael E. schrieb:

    Man muss einfach nur garantieren, dass es eine Abbruchbedingung gibt.

    Und falls diese falsch ist, hilft dir dein Debugger und wenn du nicht weißt wie der funktioniert, dann lern diesen erst kennen und arbeite dann weiter.



  • Ich würde keine Angst vor Endlosschleifen haben. Genauso wie Deadlocks keine Angst einflößen. Wenn sie auftreten, dann merkt man das schon und kann sie dann beheben.

    Im normalen Programmieralltag kommen beide Fälle so selten vor, dass man da nichts spezielles gegen unternehmen muss.



  • Michael E. schrieb:

    HumeSikkins schrieb:

    Berndoni schrieb:

    Wie teste ich denn am Besten, ob die Startposition gültig ist?

    Indem du sie vorher mit der Länge des Strings vergleichst.

    if (startPos > deinString.length()) {
       // FEHLER! Tot und Verderben
    }
    else {
        // OK.
        deinString.erase(startPos, endPos);
    }
    

    Bei startPos == deinString.length() ist auch noch Tod und Verderben.

    Nö. Ich habe vorher extra in den Standard geschaut und da steht (21.3.5.5)

    Requires: pos <= size()
    Throws: out_of_range if pos > size()



  • Berndoni schrieb:

    Was nutzt ihr denn für Hilfsmittel gegen Endlosschleifen?

    Ideen aus der formalen Programmverifikation wie z.B. Loop-Invarianten.



  • lucky_tux schrieb:

    string v = "auto";
    
      try {
        v.erase(0,9);
      }
      catch(out_of_range) {
        cerr << "range error" << endl;
      }
    

    Sorry, aber das ist ja nun wirklich mal schlecht!

    Wenn, dann schon richtig:

    catch(const out_of_range &e) {
        cerr << e.what() << endl;
    }
    


  • Wirft eigentlich jede Methode der Klasse String seine eigene Exception?
    Also werfen erase, replace, usw. alle:
    terminate called after throwing an instance of 'std::out_of_range'
    what(): basic_string::erase



  • Die Art der Exception ist abhängig vom auftretenden Ausnahmefall. Bestimmte Container können zum Beispiel ebenfalls eine Exception vom Typ out_of_range werfen. Andere Arten von Exceptions wären beispielsweise bad_alloc (Speicherreservierungsfehler), bad_cast (Typumwandlungsfehler), logic_error (logischer Fehler), uvm.



  • Aber werfen den replace und erase beide ein:
    terminate called after throwing an instance of 'std::out_of_range'
    what(): basic_string::erase

    Oder steht bei replace dann:
    terminate called after throwing an instance of 'std::out_of_range'
    what(): basic_string::replace

    ???



  • Ja what() sagt natürlich aus WAS passiert ist (warum sollte da bei replace bitteschön erase stehen?). Aber beides ist eine std::out_of_range Exception.



  • [quote="HumeSikkins"]Nö. Ich habe vorher extra in den Standard geschaut und da steht (21.3.5.5)

    Requires: pos <= size()
    Throws: out_of_range if pos > size()

    Interessant. Weshalb ist das so?



  • Weil irgendwer vom Standardisierungskomitee der Meinung war, so eine klare Definition ist besser als wenn sie "undefined behaviour" liefern würden 😉


Anmelden zum Antworten