2010-03-13 26 views
6

Warum stürzt dieser Code ab? verwendet strcat illegal auf Zeichenzeiger?Warum stürzt dieser Code ab?

#include <stdio.h> 
#include <string.h> 

int main() 
{ 
    char *s1 = "Hello, "; 
    char *s2 = "world!"; 
    char *s3 = strcat(s1, s2); 
    printf("%s",s3); 
    return 0; 
} 

bitte geben Sie einen richtigen Weg mit Bezugnahme auf Array und Zeiger.

+2

Sie strcat falsch verwenden. Es hängt die zweite Zeichenfolge an das Ende der ersten Zeichenfolge an. Die zurückgegebene Zeichenfolge ist nur eine Annehmlichkeit. Sie können eine konstante Zeichenkette (Ihre s1) nicht ändern, deshalb stürzt sie ab. s1 zeigt auf den Nur-Lese-Speicher. –

+14

Wenn alles in Ordnung wäre, würde der Code nicht abstürzen. –

+1

Vielleicht möchten Sie Ihre Frage bearbeiten, Ashish. Du wirst wahrscheinlich Downvotes bekommen, weil du sagst "selbst wenn alles perfekt ist". Es ist jedoch eine sehr gültige Frage. –

Antwort

11

Das Problem ist, dass s1 auf ein Zeichenfolgenliteral zeigt und Sie versuchen, es zu ändern, indem Sie s2 an es anfügen. Sie dürfen keine String-Literale ändern. Sie benötigen ein Zeichen-Array zu erstellen und beide Strings in es kopieren, etwa so:

char *s1 = "Hello, "; 
char *s2 = "world!"; 

char s3[100] = ""; /* note that it must be large enough! */ 
strcat(s3, s1); 
strcat(s3, s2); 
printf("%s", s3); 

„Groß genug“ bedeutet mindestens strlen(s1) + strlen(s2) + 1. Die + 1 ist für den Nullabschluss zu berücksichtigen.

Das heißt worden, sollten Sie ernsthaft in Erwägung ziehen strncat (oder die wohl besser, aber nicht dem Standard entsprechende strlcat, wenn es verfügbar ist), die Grenzen-geprüft sind, und somit weit überlegen sind strcat.

+0

Arrays mit variabler Länge (c99) oder etwas unter 100! : P –

+0

Der Grund, dass 'strcat' das erste Argument zurückgibt, ist ein Vorteil für Situationen wie diese - es bedeutet, dass Sie die Verkettung in einer Zeile durchführen können:' strcat (strcat (s3, s1), s2); ' – caf

+0

I würde tatsächlich snprintf bevorzugen, in fast jedem Fall so zu strcatcat. Es ist ein kleiner Leistungseinbruch, wird aber eher korrekt verwendet, da die korrekte Verwendung von strncat nicht mit dem Rest der Bibliothek übereinstimmt. (Das 'n' bedeutet etwas anderes, als die Leute zu denken scheinen.) –

2

Der richtige Weg in diesem Fall wäre, genügend Platz in der Zielzeichenfolge (s1) zu reservieren, um 6 zusätzliche Zeichen (s2) sowie den Nullabschluss für die Zeichenfolge zu speichern.

char s1[14] = "Hello, "; 
char *s2 = "world!"; 
char *s3 = strcat(s1, s2); 
printf("%s",s3); 
0

Hier ist ein Zitat aus dem strcat() Handbuch: „Die strcat() Funktion anhängt zum dest Zeichenfolge, die die src Zeichenfolge, den Null-Byte überschrieben wird ('\ 0') am Ende des dest, und fügt dann ein abschließendes Nullbyte hinzu. Die Zeichenfolgen dürfen sich nicht überlappen, und die Zielzeichenfolge muss genügend Platz für das Ergebnis haben. "

Das Problem hier ist, dass s1 und s2 auf statische Zeichenfolgen zeigen, die "schreibgeschützt" sind. Wenn Sie also versuchen, eine strcat-Operation mit einer solchen Zeichenfolge in den DEST-Parametern auszuführen, erhalten Sie einen Fehler.

Der beste Weg, um Ihre Hallo Welt String hier ist Malloc es so in der Lage sein, sowohl s1 und s2 zu enthalten. Vergessen Sie auch nicht, ein '\ n' am Ende Ihrer PrintF-Format-Zeichenfolge hinzuzufügen, sonst könnten Sie überrascht sein. Hier

ist der Code, den ich schreiben würde, wenn ich Sie wäre:


int main() 
{ 
    char* s1 = "Hello "; 
    char* s2 = "World !"; 
    char *s3 = malloc((strlen(s1) + strlen(s2) + 1) * sizeof(char)); 
/* +1 is for the null terminating character 
and sizeof(*s3) is the actual size of a char. */ 

    if (s3) 
    { 
    strcat(s3, s1); 
    strcat(s3, s2); 
    printf("%s\n", s3); 
    free(s3); // always free what you alloc when you don't need it anymore. 
    } 
    return 0; 
}