2017-02-22 3 views
2

Ich schrieb diesen CodeWarum ändert dieser C-Code die Zeichenfolge nicht und verursacht einen Pufferüberlauf?

#include <stdio.h> 

int main() 
{ 
    char String[] = "Hello the world!"; 
    char *pointer = String; 
    int i; 

    printf(" %s\n", pointer); 

    pointer = "Helllooooo the worlldddddd"; 
    printf("Hello %s\n", pointer); 
    printf("Hello %s\n", String); 

    return 0; 
} 

aber ich kann nicht verstehen, wie diese Linie gut funktioniert.

pointer = "Helllooooo the worlldddddd"; 

aber ich habe diese Ausgabe

Hello the world! 
Hello Helllooooo the worlldddddd 
Hello Hello the world! 

Wie sehen Sie es nicht String Wert ändern könnte, aber es zeigt mehr als die ursprüngliche Anzahl von Zeichen. Sollte dies nicht zu einem Pufferüberlauf führen? Wird das nicht andere Variablen zerstören?

+1

'" Hallo die Welt! "' Und '" Helllooooo die worldddddd "' sind zwei verschiedene Strings, die sich in zwei verschiedenen Teilen des Speichers befinden. Mit 'pointer = ...' setzen Sie 'pointer' auf die Adresse einer dieser Zeichenketten (d. H. Setzen Sie sie so, dass sie auf diese Zeichenkette zeigt). –

Antwort

6

Wenn Sie die Zeile schreiben

pointer="Helllooooo the worlldddddd"; 

Sie nicht sagen, „nehmen das Array an von pointer hingewiesen und überschreibt seinen Inhalt mit dem String "Helllooooo the worlldddddd"“, sondern „ändern die Zeichenfolgepointer Punkte bei so dass es jetzt auf die Zeichenfolge ""Helllooooo the worlldddddd" zeigt. " Dies erklärt, warum Sie die ursprüngliche Zeichenfolge beim direkten Drucken String ausgedruckt - Sie haben es nie wirklich geändert. Daher müssen Sie sich nicht darum kümmern, dass Ihr Array hier überläuft, da Sie eigentlich nichts daran schreiben.

Auf der anderen Seite, wenn Sie

strcpy(pointer, "Helllooooo the worlldddddd"); 

die eigentlich tut Kopie der Inhalt des neuen String in den Puffer an von pointer darauf schrieb, dann Sie würden einen Pufferüberlauf haben, die wäre ein Problem. Beachten Sie jedoch, dass dies eine sehr unterschiedliche Operation ist, die explizit "Bitte kopieren Sie den Inhalt dieser Zeichenfolge an diesen Speicherort" anstelle von "Ändern, wo dieser Zeiger zeigt" sagt.

+1

@JohnH - Ich glaube nicht, dass 'String' als' const' betrachtet wird, implizit oder anders, also kann zwar '' '' '' '' '' '' '' '' '' '' '' 'nicht mehr Platz bekommen. Wenn es implizit "const" wäre, würde ich denken, dass es einen Kompilierzeitfehler im Gegensatz zu einem Laufzeitfehler auslösen würde. Gibt es ein bestimmtes Umfeld, in dem Sie etwas anderes beobachtet haben? – ryyker

+1

@JohnH, nein 'String' muss veränderbar sein. Es zeigt nicht auf das String-Literal, sondern auf ein vollständig separates Array von 'char', das nicht" const "-qualifiziert ist. Per se ist es also kein Problem, sie zu modifizieren. (Es gibt natürlich ein Problem mit der Größe.) –

1

Sie haben einen Zeiger initialisiert, der auf String "Hello the world" zeigt char *pointer=String; so weit so gut.
zuerst printf printf(" %s\n",pointer);, Sie haben den Zeiger gedruckt, der auf "Hello the world" zeigt.
dann setzen Sie den Zeiger auf eine neue Zeichenfolge "Hellloooooo der Weltdddd" pointer="Helllooooo the worlldddddd"; zeigen.
dann haben Sie den Zeiger ausgedruckt, der in diesem Fall auf "Hellloooooo the worlddddd" printf("Hello %s\n",pointer); zeigt.
last printf Sie haben die Zeichenfolge "Hello the world" printf("Hello %s\n",String); gedruckt.
Hinweis :. ((takecare, die Sie im zweiten printf("Hello %s\n",String); und dritten printf printf("Hello %s\n",String); die Zeichenfolge gedruckt hallo, die vor dem Wert des Zeigers oder die Zeichenfolge gedruckt wird))

1

Eine weitere schnelle Möglichkeit für Sie zu prüfen, wenn Strings zu manipulieren:
Die String-Funktion strdup(...); ermöglicht das Kopieren einer vorhandenen Zeichenfolge in eine neu erstellte Zeichenfolge in einem einfachen Schritt.(oder zumindest eine, in der alle die Komplexität abstrahiert wurde):

char *pointer = strdup("Helllooooo the worlldddddd"); 

die neue Zeichenfolge pointer kann nun verwendet werden, um jede Zeichenfolge enthält bis zu len lang, wo len ist definiert als:

int len = strlen(pointer);//len is 26 after using strdup(...); above 

So zum Beispiel, weil Ihr Beispiel String kürzer als len:

char String[]="Hello the world!";//length is 16 

Sie es in pointer ohne einen Pufferüberlauf kopieren könnte:

strcpy(pointer, String); 

erstellt Strings strdup(...): free'd zu verwenden, müssen Speicherlecks zu vermeiden. Rufen Sie die folgende, wenn Sie fertig sind mit pointer:

free(pointer); 
1
#include <stdio.h> 

int main() 
{ 
char String[]="Hello the world"; // the string 
char *pointer=String;    // pointer to string 
char i;       //counter 

printf(" %s\n",pointer);   // print current value of pointer 

pointer="number of char";   // new value to replace the string 
for (i=0;i<14;i++)    // you cannot change the content of array without using loop 
{ 
String[i] = pointer[i];   // char i in string = ti char i in pointer 
} 
printf("Hello %s\n",pointer); // print value of pointer 
printf("Hello %s\n",String); // print value of string 

return 0; 
} 

ich denke, dass was Sie zu tun versuchen.

Verwandte Themen