Ist es legal, übergeben Sie einen nicht-null-terminierte Zeichenfolge strncmp in C?

Ich habe ein array von 16 bytes, das ist der name einer ausführbaren Datei, die segment.

char segname[16];

Wenn das segment-name Länge von weniger als 16 bytes, dann wird der rest aufgefüllt mit null-bytes. Ansonsten gibt es keine abschließende null-byte.

Möchte ich vergleichen segname zu verschiedenen strings, z.B. __text.

Ist es legal zu nennen strncmp mit einem nicht-null-terminierte Zeichenfolge?

Dieser Beitrag davon ausgegangen, dass es legal ist. Dieser source-code macht es legal zu. Aber mein Mann Seite sagt:

Den strncmp() Funktion lexikographisch vergleicht, die null-terminierte strings s1 und s2.

Die Größe übergeben strncmp wird die Größe der segname.

Frage ich mich, was ich den beziehen soll.

  • Ein char array zurück, das ist nicht '\0'-terminiert ist kein string!
  • Richtig, ich nenne es possibly null-terminated array nächste mal.
  • Sie verpasst mein Punkt! Es gibt keine string-Typ in C. Sie sollten Allerdings berücksichtigen, dass die Ausgaben extra char und beenden Sie immer das array. Das kann zu anderen string-Funktionen. Better safe than sorry!
  • Nicht sicher, dass die Mann-Seite, die Sie zitieren. Aber die POSIX-Mann-Seite, auf Ubuntu sagt „Die strncmp () – Funktion vergleichen, die nicht mehr als n bytes (Byte-Folgen ein null-byte werden nicht verglichen) von der array-Spitzen, von s1 auf das array verweist s2. „, das sollte klar sein und ist direkt aus dem C-standard. Vielleicht möchten Sie aktualisieren Sie Ihr man-pages?
  • Eigentlich bin ich Rekodieren Teil nm die analysiert Binärdateien mit mach-o-format, und ich habe nicht die Wahl, segname ist Teil der Sektion struct in der mach-o header-Dateien. Ich würde verbringen Sie einen extra char sonst. Durch die string-meinen wir null-terminated byte arrays auch wenn es keinen string-Typ in C. Bitte überprüfen Sie die Diskussion unten über den Unterschied zwischen read bytes und im Vergleich bytes`. Man-pages auf meinem Computer (osx / ubuntu) beide sprechen über Zeichenfolgen oder null-terminierte arrays, und als man pages unterscheiden sich erwartete ich ein Zitat aus dem standard.
  • Es ist nicht mir, dass Sie ein problem mit strncmp. Es ist immer gut zu Lesen, der standard, bevor Sie eine Frage stellen. Oder – wie ich schrieb – um eine richtige man-page verfügbar.

InformationsquelleAutor Bilow | 2017-01-01



2 Replies
  1. 67

    Entsprechend dem C99-standard, Abschnitt 7.21.4.4, §3., es ist legal:

    Den strncmp Funktion gibt eine Ganzzahl zurück, die größer als, gleich oder kleiner als null ist, entsprechend der möglicherweise null-terminiert array verweist s1 größer als, gleich zu oder weniger als der möglicherweise null-terminiert array verweist s2.

    Beachten Sie jedoch, dass es sagt array von Zeichen. Per definition, wenn ein array von Zeichen ist nicht null-terminiert ist, ist es nicht ein string.

    • C99 abgelöst wurde; C2011 ist der aktuelle C-standard. Die Spezifikation für strncmp() im Abschnitt 7.24.4.4, in der Tat weglassen, wird jede Anforderung, dass die arrays, die verglichen werden null-terminiert ist, jedoch.
    • Es sollte beachtet werden, jedoch, dass der Wegfall einer Voraussetzung für eine null-Terminierung nicht den Zugriff außerhalb der Grenzen entweder Eingabe-array. Es obliegt dem Aufrufer, um sicherzustellen, dass das Dritte argument ist angemessen, um zu vermeiden, die Funktion der überschreitung der Grenzen entweder array. Der Anrufer Risiken aufrufen zu undefiniertem Verhalten, wenn er ausfällt, dies zu tun.
    • Wenn der Standard gibt an, dass Zeichen followiing ein null-byte werden nicht verglichen, sollte diese ergriffen werden, zu implizieren, dass eine Umsetzung so Verhalten, als wäre es nicht Lesen, wie Zeichen? Es wäre wohl kaum ungewöhnlich, dass eine Anwendung brauchen könnte, um zu vergleichen, ein null-string [die möglicherweise fehlt ein abschließendes null, wenn es genau füllt den Puffer] mit einer null-terminiert ein [deren Puffer kann kürzer sein als die der null-string], und eine solche Garantie wäre notwendig, um strncmp geeignet für diesen Zweck.
    • Das ist eine ausgezeichnete Frage, @supercat. Die standard nicht explizit sagen, was Teile des Eingabe-arrays sind Lesen, nur über die Zeichen im Vergleich. Da das gilt auch für die n-Zeichen-Grenze, die Interpretation, die Funktion zu geben, beliebiger garantieren nützlich für die Gewährleistung definiert Verhalten erfordert die Einnahme es zu bedeuten, dass kein Zeichen gelesen werden, andere als die, die verglichen werden. Dennoch sehe ich es als ein best-practice-festlegen der n – argument nicht größer als die Größe des kleineren Arrays.
    • Am Anfang der Abschnitt, der erklärt <string.h>, der standard sagt, dass das argument n gibt die Länge des Arrays. strncmp auch nicht erforderlich NULs. Dies bedeutet, dass nichts vor s1 oder s2 und nichts bei oder über der s1+n oder s2+n zugegriffen wird.
    • Unklar ist, auf „ein null-string [die möglicherweise fehlt ein abschließendes null, wenn es genau füllt den Puffer]“ Wie kann ein Zeichenfolge fehlt ein abschließendes null-Zeichen?
    • Interessanter Fall „n ist größer als die array-Größe s2, aber strlen(s1)<n (oder kleiner als die Größe der array-s2)“ in Ihrer jetzt gelöscht comment. Ich vermute, es ist UB
    • Kommen Sie, daran zu denken, im schlimmsten Fall wird die Implementierung hat Zugriff auf alle Zeichen des s1 im Vergleich. Nicht zu vergleichen, Zeichen bei verschiedenen lags aus Ihren Zeigern. Ich bin versucht zu sagen, dass, wenn s1 ist beendet null und kleiner als s2, dann s2 wird nur zugegriffen werden, auf seiner ersten strlen(s1) Zeichen. Aber ich bin mir nicht sicher.
    • Ich nehme supercat zu Fragen, nicht was wir denken, sollte geschehen ist, sondern was der standard erfordert geschehen. Diese sind nicht unbedingt das gleiche.
    • Wie Sie vorher sagten, dass der standard nicht explizit in diesem Fall. Also, wenn ich sage „ich denke X passieren soll“, ich bin nicht einfach nur aus dem blauen heraus. Es ist meine interpretation von, was die Folgen der standard ist offen. Ich bin nicht sicher, dass meine interpretation korrekt ist, aber ich würde mich freuen, wenn es jemand Lesen könnte, der etwas aus der Norm, die gab uns eine definitive Antwort.
    • Meine Frage war, ob einer der nachfolgenden Dokumente haben geklärt, was erforderlich ist. Was sollte eigentlich egal ist, ob alle vorhandenen Programme angewiesen sind, auf ein bestimmtes Verhalten, und ob es Implementierungen, in denen garantiert ein solches Verhalten würde teuer werden; wenn die Antwort auf die erste Frage ist „ja“, und die zweite, „no“, der Standard sein sollte als Pflicht Verhalten. Leider, solches denken ist nicht nie aus der Mode in diesen Tagen.
    • Das design der Standard-Bibliothek im Allgemeinen wird davon ausgegangen, dass, mit Ausnahme von memcpy/memmove, ist es besser, eine Funktion, die verwendet werden kann für alles, als zu haben andere Funktionen, optimiert für verschiedene Zwecke. Eine version von strncmp, die nur benötigt, um zu berichten, ob null-gepolsterte strings gleich waren und durfte-aber nicht vorausgesetzt-Verarbeitung beendet wird, wenn es gefunden, ein mismatch oder ein null-byte–schneller sein könnte als ein strncmp, was nicht erlaubt ist, etwas zu Lesen, nachdem ein null-byte, aber der Standard macht keine Rückstellungen für das so eine Sache.

  2. 15

    Die strncmp-Funktion vergleicht nicht mehr als n Zeichen (in der
    nach einem null-Zeichen werden nicht verglichen) aus dem Feld wies
    von s1 auf das array verweist s2.

    Spezifikation 7.24.4.2 sagt, dass.C11-standard.

    Zeichen, die nicht Folgen einer null-charcaters werden nicht verglichen, so rechnet es null endete-zeichenarray oder-Zeichenfolge.1

    Können Sie nicht-null-Zeichen beendet auch hier, aber in diesem Fall haben wir zum angeben der Länge bis zu die wir haben, um es zu überprüfen, welche ist in einigen Fällen sinnvoll.

    Korrekturen


    [1] Dass Zeichen, die nicht Folgen ein null-Zeichen werden nicht verglichen, bedeutet nicht, dass strncmp erwartet, dass null-terminierte “ strings. Es bedeutet nur, dass strncmp braucht einen speziellen Fall so zu sagen (zum Beispiel), die abc\0def… und abc\0xyz… Vergleich gleich. Es ist nichts falsch mit dem Vergleich von zwei char-arrays, die nicht null-terminiert (bis zu der angegebenen Länge) oder Vergleich von null-terminiertes char-array mit einem anderen, der nicht null-terminiert

    Das ist direkt aus dem Kommentar von David Hammen

    • Hinweis: „… Folgen ein NULL-charcaters….“ macht mehr Sinn als „… Folgen ein null-Zeichen … „. NULL ist die null-Zeiger-Konstanten im Zusammenhang mit Zeigern. Speichern Sie die groß – NULL für die Diskussion über Zeiger.
    • Oder Sie können schreiben, NUL, wie es ist in der Regel bezeichnet im ASCII-und ASCII-standards abgeleitet.
    • C nicht angegeben ist ASCII, aber Häufig tut. Das ist, warum NUL (ASCII definierten Wert) ist nicht in der C-Spezifikation (außer in einer nicht-normativen Fußnote.) Eine gute alternative zu den null-Zeichen ist '\0'. Siehe dieser
    • Wahr. Aber ich habe nicht erwähnt ASCII-was darauf hindeutet, alle Bindungen an die Sprache. Nur, dass, angesichts Ihrer Bedeutung, werden Sie wahrscheinlich bekommen, sich selbst zu verstehen, ohne Gefahr der Verwirrung, wenn Sie schreiben, NUL statt null-Zeichen \0 oder einfach 0.
    • Wie es passiert, EBCDIC bezieht sich auch auf das null-Zeichen als NUL. Auf der anderen Seite, C ermöglicht anderen Zeichensatz als ASCII und EBCDIC. Auf der anderen Seite, ich habe noch nie gehört, eine C-Implementierung, die verwendet einen Zeichensatz nicht auf der Grundlage von entweder ASCII-oder EBCDIC.
    • Zeichen, die nicht Folgen einer null-charcaters werden nicht verglichen, so rechnet es null endete-zeichenarray oder-Zeichenfolge„: diese Antwort ist falsch. Der text, den du zitiert hast stellt eine Einschränkung für strncmp: es wird nie vorbei liest ein null-Zeichen, , wenn vorhanden. Es gibt nicht vor, eine Voraussetzung, dass es ein null-Zeichen. Auch mit strncmp Sie immer haben, geben Sie die maximale Anzahl der Zeichen, die überprüft werden soll.
    • Ich habe angegeben, ist der zweite Teil und auch der erste Teil…Wirklich, wenn es spiegelt irgend etwas anderes, dann ist es meine Schuld… vielleicht können Sie vorschlagen und Bearbeiten…Manchmal passiert es, dass die Art und Weise Sie die Worte geben den Menschen falsche Bedeutung, und es ist falsch..würden Sie bitte vorschlagen, eine Bearbeiten?
    • Über ein edit: dieses Problem Beheben: “ Zeichen, die Folgen nicht ein null-charcaters werden nicht verglichen, so rechnet es null endete Zeichen-array oder einen string. Dass Zeichen, die nicht Folgen ein null-Zeichen werden nicht verglichen, bedeutet nicht, dass strncmp erwartet, dass null-terminierte “ strings. Es bedeutet nur, dass strncmp braucht einen speziellen Fall so zu sagen (zum Beispiel), die abc\0def... und abc\0xyz... Vergleich gleich. Es ist nichts falsch mit dem Vergleich von zwei char-arrays, die nicht null-terminiert (bis zu der angegebenen Länge) oder Vergleich von null-terminiertes char-array mit einem anderen, der nicht null-terminiert.
    • Hinzugefügt habe ich Ihren Kommentar…hoffe, dass Sie don t Geist. Wenn Sie möchten, mir zu schreiben, eine version, die auf meinem eigenen ich kann das auch…bitte lassen Sie mich wissen.
    • FWIW, ich nahm wieder mein downvote nach Ihrem ersten edit in der Antwort.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.