strlen prüft nicht auf NULL

Lesezeit: 6 Minuten

Benutzeravatar von Hari
Hari

Warum ist strlen() nicht auf NULL prüfen?

wenn ich mache strlen(NULL)die Programmsegmentierungsfehler.

Versuchen, die Begründung dahinter zu verstehen (falls vorhanden).

  • Bitte beachten Sie, dass strlen und andere String-Funktionen vor etwa 10 Jahren vor der Verarbeitung nach Null-Strings gesucht haben, dies jedoch entfernt wurde, da die meisten Programmierer diese Zeiger sowieso explizit überprüft haben und es sinnlos war, sie zweimal zu überprüfen.

    – Eule

    5. März 2017 um 16:05 Uhr

Hogans Benutzeravatar
Hogan

Die Begründung dahinter ist einfach: Wie kann man die Länge von etwas überprüfen, das nicht existiert?

Außerdem gibt es im Gegensatz zu “verwalteten Sprachen” keine Erwartung, dass das Laufzeitsystem ungültige Daten oder Datenstrukturen korrekt handhabt. (Diese Art von Problem ist genau der Grund, warum “modernere” Sprachen für Anwendungen ohne Berechnung oder weniger Leistung beliebter sind).

Eine Standardvorlage in c würde so aussehen

 int someStrLen;

 if (someStr != NULL)  // or if (someStr)
    someStrLen = strlen(someStr);
 else
 {
    // handle error.
 }

  • “Managed” … Das ist richtig. Stellen Sie sich vor, jede Funktion beginnt sehr paranoid und sucht nach möglichen Fehlern. Printf speichert Metainformationen für jedes Argument in der Liste, jede mathematische Operation prüft auf Überlauf usw. Das ist verwaltet.

    Benutzer405725

    26. April 2011 um 20:42 Uhr

  • Ich lehne die “Standardvorlage” ab. Wenn someStr auf einen String zeigen soll, sollte er niemals ein Nullzeiger sein, wenn dieser Punkt im Programm erreicht ist. Einige Leute verwenden Nullzeiger als speziellen “leeren” Wert, aber das ist keine universelle Konvention und ich würde sagen, es schadet viel mehr als es nützt …

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    5. Februar 2012 um 1:20 Uhr

  • @RI denke, wir sind uns nicht einig darüber, was “Standardvorlage” bedeutet. Vielleicht bevorzugen Sie “nützliches Muster”? Wenn Sie sich mit diesem Begriff besser fühlen, bin ich damit einverstanden.

    – Hogan

    5. Februar 2012 um 18:44 Uhr

  • In c11 gibt es strnlen_s(str, strsz) die Null zurückgibt, wenn str ein Nullzeiger ist.

    – jfs

    28. Oktober 2017 um 13:52 Uhr

  • @jfs es tut mehr als das, es begrenzt auch die maximal zurückgegebene Größe. Aber Sie machen deutlich, dass dies eindeutig die bessere Wahl für ein robustes Programm ist.

    – Hogan

    29. Oktober 2017 um 14:08 Uhr

Der Teil der Sprache Standard die die Zeichenfolgenbehandlungsbibliothek definiert, gibt an, dass, sofern nicht anders für die spezifische Funktion angegeben, alle Zeigerargumente muss gültige Werte haben.

Die Philosophie hinter dem Design der C-Standardbibliothek ist, dass der Programmierer letztendlich am besten wissen kann, ob eine Laufzeitprüfung wirklich durchgeführt werden muss. Damals, als Ihr gesamter Systemspeicher in Kilobyte gemessen wurde, war der Aufwand für die Durchführung einer nicht notwendig Laufzeitprüfung könnte ziemlich schmerzhaft sein. Die C-Standardbibliothek macht sich also nicht die Mühe, diese Prüfungen durchzuführen; Es geht davon aus, dass der Programmierer es bereits getan hat, wenn es wirklich notwendig ist. Wenn du kennt Sie werden niemals einen schlechten Zeigerwert übergeben strlen (z. B. Sie übergeben ein String-Literal oder ein lokal zugewiesenes Array), dann müssen Sie die resultierende Binärdatei nicht mit einem überladen nicht notwendig gegen NULL prüfen.

  • +1 für “Wenn Sie wissen, dass Sie niemals einen schlechten Zeigerwert übergeben werden”.

    – Blagovest Buyukliev

    26. April 2011 um 21:32 Uhr

  • “Die Portion” ist C17 7.1.4.1.

    – Allee Milia

    4. April 2021 um 12:49 Uhr

Benutzeravatar von ninjalj
ninjalj

Der Standard verlangt dies nicht, sodass Implementierungen nur einen Test und möglicherweise einen teuren Sprung vermeiden.

Ein kleines Makro zur Trauerbewältigung:

#define strlens(s) (s==NULL?0:strlen(s))

Drei wesentliche Gründe:

  • Die Standardbibliothek und die C-Sprache sind so konzipiert, dass sie davon ausgehen, dass der Programmierer weiß, was er tut, sodass ein Nullzeiger nicht als Grenzfall behandelt wird, sondern eher als Programmierfehler, der zu undefiniertem Verhalten führt.

  • Es entsteht Laufzeit-Overhead – Aufrufen strlen tausendmal und immer dabei str != NULL ist nicht angemessen, es sei denn, der Programmierer wird wie ein Weichei behandelt;

  • Es summiert sich zur Codegröße – es könnten nur ein paar Anweisungen sein, aber wenn Sie dieses Prinzip übernehmen und überall anwenden, kann es Ihren Code erheblich aufblähen.

  • Einige Standard-C-Funktionen suchen nach NULL Eingaben, also ist der erste Grund falsch. Der dritte Grund ist ebenfalls falsch, da das Einfügen einiger zusätzlicher Überprüfungen in die Bibliothek weniger zur Codegröße hinzufügt (auf einer typischen, nicht eingebetteten Plattform) als alle Überprüfungen, die in den Clientcode eingefügt werden.

    – Fred Foo

    26. April 2011 um 21:02 Uhr


  • @larsmans: Grund eins war keine ultimative Aussage, sondern ein Versuch, die vorherrschende Denkweise in der C-Programmierung zu beschreiben; Grund drei macht Sinn, wenn Sie sicher sind, dass der Zeiger nicht sein kann NULL im Client-Code und eine solche Prüfung wirkt eher wie eine assert Aussage.

    – Blagovest Buyukliev

    26. April 2011 um 21:21 Uhr

  • @larsmans: oh, aber die meisten Funktionen, die prüfen NULL sind auf “neuere” Teile des Standards (zB: mb*, wc*), nicht wahr?

    – ninjalj

    26. April 2011 um 21:25 Uhr

  • @ninjalj: Und die Überprüfung auf NULL ist eigentlich der größte Fehler in den wc/mb-Schnittstellen. Eine häufige Notwendigkeit bei diesen Funktionen besteht darin, jeweils ein einzelnes Byte/Zeichen gleichzeitig zu verarbeiten, und die Durchführung mehrerer nutzloser Nullzeigerprüfungen bei jedem Aufruf kann die dafür aufgewendete Zeit leicht verdoppeln.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    5. Februar 2012 um 1:22 Uhr

  • @R ..: sicher, ich habe nur darauf hingewiesen, dass die Existenz dieser Funktionen kein wirkliches Gegenbeispiel zu Blagovests erstem Punkt darstellt.

    – ninjalj

    14. Februar 2012 um 23:52 Uhr

Benutzeravatar von Casey Flynn
Casey Flynn

size_t strlen ( const char * str );

http://www.cplusplus.com/reference/clibrary/cstring/strlen/

Strlen nimmt einen Zeiger auf ein Zeichenarray als Parameter, null ist kein gültiges Argument für diese Funktion.

  • Einige Standard-C-Funktionen suchen nach NULL Eingaben, also ist der erste Grund falsch. Der dritte Grund ist ebenfalls falsch, da das Einfügen einiger zusätzlicher Überprüfungen in die Bibliothek weniger zur Codegröße hinzufügt (auf einer typischen, nicht eingebetteten Plattform) als alle Überprüfungen, die in den Clientcode eingefügt werden.

    – Fred Foo

    26. April 2011 um 21:02 Uhr


  • @larsmans: Grund eins war keine ultimative Aussage, sondern ein Versuch, die vorherrschende Denkweise in der C-Programmierung zu beschreiben; Grund drei macht Sinn, wenn Sie sicher sind, dass der Zeiger nicht sein kann NULL im Client-Code und eine solche Prüfung wirkt eher wie eine assert Aussage.

    – Blagovest Buyukliev

    26. April 2011 um 21:21 Uhr

  • @larsmans: oh, aber die meisten Funktionen, die prüfen NULL sind auf “neuere” Teile des Standards (zB: mb*, wc*), nicht wahr?

    – ninjalj

    26. April 2011 um 21:25 Uhr

  • @ninjalj: Und die Überprüfung auf NULL ist eigentlich der größte Fehler in den wc/mb-Schnittstellen. Eine häufige Notwendigkeit bei diesen Funktionen besteht darin, jeweils ein einzelnes Byte/Zeichen gleichzeitig zu verarbeiten, und die Durchführung mehrerer nutzloser Nullzeigerprüfungen bei jedem Aufruf kann die dafür aufgewendete Zeit leicht verdoppeln.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    5. Februar 2012 um 1:22 Uhr

  • @R ..: sicher, ich habe nur darauf hingewiesen, dass die Existenz dieser Funktionen kein wirkliches Gegenbeispiel zu Blagovests erstem Punkt darstellt.

    – ninjalj

    14. Februar 2012 um 23:52 Uhr

1389800cookie-checkstrlen prüft nicht auf NULL

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy