2010-10-29 6 views

Antwort

5

Wenn Sie ein char-Array übergeben werden, das möglicherweise null-terminierte Daten enthält, gibt es wirklich keine gute Möglichkeit, dies zu überprüfen. Das Beste, was Sie tun können, ist die Suche nach einem Nullzeichen bis zu einer bestimmten Länge (nicht unbegrenzt!). Aber 0 ist nicht gerade ein ungewöhnliches Datenbyte, das in einem nicht initialisierten Speicherbereich zu finden ist.

Dies ist eines der vielen Dinge über C Defacto String-Standard, die viele Menschen nicht mögen. Wenn Sie die Länge einer Zeichenfolge ermitteln, die ein Client Ihnen übergibt, ist dies im besten Fall eine O (n) -Suchoperation und im schlimmsten Fall eine Segmentierungsstörung.

Ein weiteres Problem ist natürlich, dass Arrays und Zeiger austauschbar sind.Das bedeutet array_name + 2 ist das gleiche wie &(array_name[2]) und sizeof(a) ist sizeof(char*), nicht die Länge des Arrays.

11

Sie erhalten 4, weil das die Größe eines Zeigers auf Ihrem System ist. Wenn Sie die Länge einer Null-terminierten Zeichenfolge erhalten möchten, möchten Sie die Funktion strlen in der C-Standardbibliothek verwenden.

+0

'strnlen' für die Sicherheit. – nmichaels

+0

'strnlen' ist plattformspezifisch, nicht im Standard. – jer

+6

@Nathon: 'strnlen' fügt nicht wirklich Sicherheit hinzu, oder? Wenn für Ihre Funktion eine nullterminierte Zeichenfolge erforderlich ist und keine Zeichenfolge abgerufen wird (oder wenn eine Funktion als null-terminierte Zeichenfolge zurückgegeben wird und keine zurückgegeben wird), ist der Code bereits ungültig. –

28

sizeof(a) gibt Ihnen die Größe des Zeigers, nicht des Arrays von Zeichen, auf die der Zeiger zeigt. Es ist das gleiche wie wenn Sie sizeof(char*) gesagt hätten.

Sie müssen strlen() verwenden, um die Länge eines nullterminierten String zu berechnen (beachten Sie, dass die Länge zurück nicht den Null-Terminator enthalten, so strlen("abcd") 4, nicht 5). Oder können Sie ein Array mit dem Stringliteral initialisieren:

char a[] = "abcd"; 
size_t sizeof_a = sizeof(a); // sizeof_a is 5, because 'a' is an array not a pointer 

Die Stringliteral "abcd" ist null beendet; Alle String-Literale sind null-terminiert.

+1

Das OP hat bereits 'const' benutzt, daher ist' const char a [] 'wahrscheinlich eine bessere Idee als' char a [] '. – aschepler

+4

Um weiter zu klären, gibt 'strlen()' nur die logische Länge der Daten im char-Array an, nicht die Anzahl der dafür zugewiesenen Bytes. Ich glaube nicht, dass es einen Weg gibt, diese Nummer zu bekommen. –

4

sizeof(a) ist sizeof(const char*), die Größe des Zeigers. Es wird nicht durch den Inhalt von a beeinflusst. Dafür wollen Sie strlen.

Außerdem sind alle String-Literale mit doppeltem Anführungszeichen wie "abcd" im Quellcode automatisch null-terminiert.

1

sizeof (a) gibt die Größe des const char *a zurück ... nicht die Größe dessen, auf das es zeigt. Sie können strlen(a) verwenden, um die Länge der nullterminierten Zeichenfolge zu ermitteln, und nein, das Ergebnis von strlen enthält den Nullterminator nicht.

6

Das Problem hier ist, dass Sie sizeof() verwirren, die eine Kompilierzeitoperation mit der Länge einer Zeichenfolge ist, die eine Laufzeitoperation ist. Der Grund erhalten 4 zurück, wenn Sie sizeof(a) ausführen, ist, dass a ist ein Zeiger und die typische Größe eines Zeigers in C ist 4 Bytes. Um die Länge der Zeichenfolge zu erhalten, verwenden Sie strlen.

Für die zweite Frage, wie Sie sicherstellen, dass eine Zeichenfolge null terminiert ist. Die einzige Möglichkeit, dies definitiv zu tun, besteht darin, die Zeichenfolge selbst zu beenden. Bei nur char* gibt es keine Möglichkeit, zu 100% zu garantieren, dass es ordnungsgemäß null terminiert ist. Es muss sehr sorgfältig darauf geachtet werden, dass der Vertrag zwischen dem Hersteller und dem Verbraucher der Nummer char* dahingehend verstanden wird, wer die Zeichenfolge beendet.

+0

aah .... dumm mich. Aber wenn ich strlen (a) bekomme ich 4, und ich weiß, dass ein "abcd" (von gdb) hat. – hari

+0

@hari, 4 ist korrekt, da die Länge der Zeichenfolge "abcd" tatsächlich 4 ist. Die Speicheranforderungen für "a" sind jedoch "strlen (a) + 1", um den Nullabschluss zu verarbeiten. Dies ist einer der Teile von C, die nur ein bisschen gewöhnungsbedürftig sind. – JaredPar

+0

Das liegt daran, dass die Länge von "abcd" 4 ist. Strlen zählt den Null-Terminator nicht. – jer

Verwandte Themen