std::vector Fragen



  • Hallo Leute,

    _1_
    Wo ist der Unterschied zwischen dem Zugriff auf den std::vector in folgendem Beispiel? at() kann eine Exception werfen. Ist da sonst noch was. Ist eines schneller? Warum?

    std::vector<int> vec;
    for (unsigned int i = 0; i < vec.size(); ++i)
    {
      cout << vec[i] << endl;      // Möglichkeit A
      cout << vec.at(i) << endl;   // Möglichkeit B
    }
    

    _2_
    Wie sind die Elemente eines vector im Speicher angeordnet? Sequentiell?

    THX



  • 1. Es gibt keinen weiteren, nennenswerten Unterschied, bis auf die Tatsache mit der out_of_range-Exception bei at() und dem segfault bei operator []() bei fehlerhaftem Zugriff.

    2. Die Anordnung im Speicher ist nicht vom Standard definiert. Aber generell ist es ein dynamisches Array.



  • Ist at() dann nicht auch langsamer als []()?

    Ich meine irgendwo in EffectiveC++ hätte gestanden, das Exceptions den Code merklich langsamer machen?!



  • > Ich meine irgendwo in EffectiveC++ hätte gestanden, das Exceptions den Code merklich langsamer machen?!

    Exceptions heißen immernoch "Ausnahme", d.h. die meisten Zugriffe mit at() sollten keine Ausnahmen auslösen. Demnach sind diese Operationen genauso schnell wie operator [](). Wenn eine Ausnahme geworfen wird, muss man erst in die Ausnahmebehandlung, das nimmt natürlich ein paar Millisekunden (wenn überhaupt) Zeit in Anspruch (also alles andere als "merklich"), aber besser als ein Segmention Fault und Programm-Crash, oder?
    :xmas1:



  • Ad aCTa schrieb:

    ...2. Die Anordnung im Speicher ist nicht vom Standard definiert. Aber generell ist es ein dynamisches Array....

    Der Standard schreibt die Anordnung der Elemente vor, nämlich brav angrenzend hintereinander.



  • Programm-Crash heißt immernoch "Programm-Unfall". 😉

    Das die Ausnahmebehandlung Zeit braucht ist klar, aber so weit ich Meyers recht im Kopf habe, wird der Code auch langsamer, wenn Ausnahmen möglich sind. Muss da nochmal nachschauen.

    Ad aCTa schrieb:

    ..aber besser als ein Segmention Fault und Programm-Crash, oder?

    Generell ja, aber was soll in einer solchen Schleife (s.o.) schief gehen?



  • Ad aCTa schrieb:

    Exceptions heißen immernoch "Ausnahme", d.h. die meisten Zugriffe mit at() sollten keine Ausnahmen auslösen. Demnach sind diese Operationen genauso schnell wie operator []().

    Natürlich nicht. Irgendwo muss noch mindestens ein if drinstehen, das den Index prüft. Und das ist schon mal langsamer, wenn auch oft vernachlässigbar.

    Ad aCTa schrieb:

    aber besser als ein Segmention Fault und Programm-Crash, oder?

    Vor allem aber besser als undefiniertes Verhalten. Ein Crash ist immer noch das beste, was einem passieren kann.


  • Mod

    Ich fragte mich schon immer: Kann mir mal jemand ein Beispiel nennen, wo .at() in Releasecode Sinn macht? Irgendwie kann ich mir keinen sinnvollen Fall ausdenken, wo man Bereichsgrenzen prüfen muss, außer das Programm ist ohnehin schon fehlerhaft...



  • SeppJ schrieb:

    Ich fragte mich schon immer: Kann mir mal jemand ein Beispiel nennen, wo .at() in Releasecode Sinn macht? Irgendwie kann ich mir keinen sinnvollen Fall ausdenken, wo man Bereichsgrenzen prüfen muss, außer das Programm ist ohnehin schon fehlerhaft...

    Geht mir gleich, ich habe at() noch fast nie verwendet. Einmal, da wollte ich Daten aus einer Datei in einen std::vector einlesen, auf dessen Elemente danach hardcodiert zugegriffen wurde. Aber die Thematik hat sich erledigt, seit ich mir einen konfortableren Dateileser/-schreiber mit eigenen Sicherheitsprüfungen programmiert habe...



  • Sehe ich ähnlich. std::vector::at halte ich auch für weitestgehend sinnlos. Wie ich auch schon mal in einem anderen Thread gesagt habe, fände ich es besser, wenn die Prüfung standardmässig in std::vector::operator[] drin wäre und wenn man sie nicht wünscht, dann könnte man es ja mit einem define oder so ausschalten. Im Release wirds ja sowieso weggelassen..



  • drakon schrieb:

    Wie ich auch schon mal in einem anderen Thread gesagt habe, fände ich es besser, wenn die Prüfung standardmässig in std::vector::operator[] drin wäre und wenn man sie nicht wünscht, dann könnte man es ja mit einem define oder so ausschalten. Im Release wirds ja sowieso weggelassen..

    so ists doch schon - nennt sich assert ;P
    was anderes fänd ich auch nicht komfortabler... (jedes mal nen makro ändern halte ich auch nicht gerad für komfortabel :P)
    ich hab at zwar glaube auch noch nie verwendet, aber ich hab mit sicherheit auch andere teile der standard-lib noch nie verwendet ;P

    bb



  • drakon schrieb:

    Wie ich auch schon mal in einem anderen Thread gesagt habe, fände ich es besser, wenn die Prüfung standardmässig in std::vector::operator[] drin wäre und wenn man sie nicht wünscht, dann könnte man es ja mit einem define oder so ausschalten.

    Ich kann mich hier unskilled anschliessen. Eine Assertion im Debug-Modus reicht, die soll man meiner Meinung nach auch nicht ausschalten können. Im Release-Modus hat man Performance und im Debug-Modus Sicherheit.

    drakon schrieb:

    Im Release wirds ja sowieso weggelassen..

    Warum sowieso? at() ist ja gerade für den Release-Modus konzipiert.



  • Naja. Ich meinte, dass die Exception im [] geworfen wird, weil man ja eher den, als at braucht. Von dem her bringt mir at nix, wenn ich nicht brauche.. Da habe ich lieber die Exception im [] und wenn ich explizit nicht brauche, schalte ich halt irgendwie von at auf das normale assert um. So fände ich es sinnvoller.

    Aber wahrscheinlich ist das auch ein wenig Geschmackssache..


Anmelden zum Antworten