2012-03-30 8 views
37
#include "stdio.h" 
#include "string.h" 

main() 
{ 

    char string[] = "october"; // october is 7 letters 

    strcpy(string, "september"); // september is 9 letters 

    printf("the size of %s is %d and the length is %d\n\n", string, sizeof(string), strlen(string)); 

    return 0; 
} 

Ausgang:Sizeof vs Strlen

die Größe September ist 8 und die Länge beträgt 9

Gibt es etwas falsch mit meiner Syntax, oder was?

+10

Sie schreiben über das Ende des Feldes 'string'. Dies ist ein nicht definiertes Verhalten. 'string' kann nur 8 Zeichen enthalten (7 für" oktober "und 1 für den Nullabschluss). Wenn Sie 'strcpy' aufrufen, schreiben Sie 10 Zeichen (9 für" September "und 1 für den Nullabschluss), was bedeutet, dass Sie über das Ende des Arrays hinausgegangen sind und den angrenzenden Speicher überschreiben. – Marlon

+11

Beachten Sie, dass 'sizeof' zu * compile * Zeit berechnet wird, während 'strlen' Laufzeit ist. – Naveen

+5

@Naveen: Seien Sie sich bewusst, dass das nicht unbedingt stimmt, wo VLAs beteiligt sind. – caf

Antwort

1

Ihr Ziel-Array ist 8 Bytes (Länge von "Oktober" plus \ 0) und Sie möchten 9 Zeichen in diesem Array einfügen.

man strcpy sagt: Wenn die Zielzeichenfolge eines Strcpy() nicht groß genug ist, kann alles passieren.

Bitte sagen Sie mir, was Sie wirklich tun wollen, weil dieser schlecht langen Weg riecht

+0

Dies ist das Testprogramm zum Verständnis der Funktionsweise von sizeof() – beparas

33

sizeof und strlen() verschiedene Dinge tun. In diesem Fall wird Ihre Erklärung

char string[] = "october"; 

ist die gleiche wie

char string[8] = "october"; 

so kann der Compiler sagen, dass die Größe der string 8. ist Es tut dies bei der Kompilierung.

Allerdings zählt strlen() die Anzahl der Zeichen in der Zeichenfolge zur Laufzeit. Also, nachdem Sie strcpy() anrufen, enthält string jetzt "September". strlen() zählt die Zeichen und findet 9 von ihnen. Beachten Sie, dass Sie nicht genug Platz für string reserviert haben, um "September" zu halten. Dies ist ein nicht definiertes Verhalten.

3

die Ausgabe korrekt ist, weil

erste Anweisung Stringgröße von Compiler zugewiesen wurde, die 7 + 1 (Oktober ist 7 Byte & 1 Byte für Nullabschluss bei der Kompilierung)

Zweite Aussage: Sie sind Kopieren September (9 Bytes zu 8 Bytes Zeichenfolge);

für Sie da bekam Größe September als 8 Bytes (noch strlen() wird für September nicht funktioniert es nicht null Charakter hat)

+1

Das Stringliteral '" september "' enthält implizit das Nullzeichen, also 'strlen()' wird funktionieren, wenn das Programm noch nicht abgestürzt ist (aufgrund des Schreibens nach dem Ende des 'string' Arrays) –

-1

Sie buffer overflow Problem in diesem Beispiel beseitigen müssen. Eine Möglichkeit, dies zu tun - ist strncpy zu verwenden:

memset(string, 0, sizeof(string)); 
strncpy(string, "september", sizeof(string)-1); 
+1

Nein, nein, nein. 'strncpy()' ist trotz seines Namens das falsche Werkzeug, um etwas mit ** strings ** zu tun. Im obigen Beispiel ist die resultierende "Zeichenfolge" keine * Zeichenfolge *, weil keines ihrer 8 Elemente einen Null-Terminator enthält. – pmg

+0

Warum falsches Werkzeug? Ich habe ein Problem mit der Terminierung von Strings behoben. –

+0

Es ist das falsche Werkzeug für Strings, weil es nicht den Null-Terminator berücksichtigt, der per Definition in jedem einzelnen String existiert ('strncpy()' design macht es nur für ... errr ... * un-terminated nützlich Zeichenketten *). Stellen Sie sicher, dass Sie Platz haben und verwenden Sie 'strcpy()' (oder, wenn Sie BSD-Ismen verwenden können, verwenden Sie 'strlcpy()'). – pmg