Ich versuche zu verstehen, warum der folgende Code illegal ist:
%Vor% Was macht der Compiler, wenn er auf char *c = "hello";
trifft?
So wie ich es verstehe, ist es ein automatisches Array von Zeichen, und c
ist ein Zeiger auf das erste Zeichen. Wenn dies der Fall ist, ist c[3]
wie *(c + 3)
und ich sollte die Zuweisung vornehmen können.
Ich versuche nur zu verstehen, wie der Compiler funktioniert.
String-Konstanten sind unveränderlich. Sie können sie nicht ändern, auch wenn Sie sie einem char *
zuweisen (also weisen Sie sie einem const char *
zu, damit Sie nicht vergessen).
Um etwas detaillierter zu werden, entspricht Ihr Code in etwa:
%Vor% Dieser ___internal_string
wird oft einem schreibgeschützten Datensegment zugewiesen - jeder Versuch, die Daten dort zu ändern, führt zu einem Absturz (streng genommen können auch andere Ergebnisse vorkommen - dies ist ein Beispiel für 'undefiniertes Verhalten') . Aus historischen Gründen erlaubt Ihnen der Compiler jedoch, einem char *
zuzuordnen, was Ihnen den falschen Eindruck vermittelt, Sie könnten ihn modifizieren.
Beachten Sie, dass dies funktioniert, wenn Sie dies getan haben:
%Vor%Dies liegt daran, dass wir ein nicht-konstantes Zeichen-Array initialisieren. Obwohl die Syntax ähnlich aussieht, wird sie vom Compiler unterschiedlich behandelt.
es gibt einen Unterschied zwischen diesen:
%Vor%und
%Vor%Im ersten Fall reserviert der Compiler Platz auf dem Stack für 6 Bytes (d. h. 5 Bytes für "Hallo" und einen für den Null-Terminator.
Im zweiten Fall generiert der Compiler eine statische Konst-Zeichenkette namens "Hallo" in einem globalen Bereich (aka Stringliteral ) und weist einen Zeiger auf den Stack zu, der initialisiert wird, um auf diesen const zu zeigen Zeichenfolge.
Sie können eine const-Zeichenkette nicht ändern, und deshalb erhalten Sie einen segfault.