String Literale

8

Ich habe wenig Zweifel über String-Literale in C ++.

%Vor%

Nun werden strPtr und strArray als Zeichenfolgenliterale betrachtet.

Nach meinem Verständnis werden String-Literale im Nur-Lese-Speicher gespeichert, so dass wir ihre Werte nicht ändern können.

Wir können nicht

%Vor%

Beide obigen Aussagen sollten illegal sein. Compiler sollte in beiden Fällen Fehler werfen.

Der Compiler speichert String-Literale im Nur-Lese-Speicher. Wenn wir also versuchen, sie zu modifizieren, gibt der Compiler Fehler aus.

Auch const-Daten werden als schreibgeschützt betrachtet.

Ist es so, dass sowohl String-Literale als auch const-Daten gleich behandelt werden? Kann ich Konstanten mit const_cast aus dem String-Literal entfernen? Kann ich den Wert ändern?

Wo genau werden String-Literale gespeichert? (im Datenbereich des Programms)

    
anand 05.04.2009, 06:40
quelle

3 Antworten

16
  

Nun werden strPtr und strArray als Zeichenfolgenliterale betrachtet.

Nein, sind sie nicht. String-Literale sind die Dinge, die Sie in Ihrem Code sehen. Zum Beispiel die "Hello" . strPtr ist ein -Zeiger für das Literal (das jetzt in der ausführbaren Datei kompiliert ist). Beachten Sie, dass es const char * sein sollte; Sie können die const nicht nach dem C-Standard entfernen und erwarten ein definiertes Verhalten bei der Verwendung. strArray ist ein Array, das eine Kopie des Literals enthält (kompiliert in der ausführbaren Datei).

  

Beide obigen Aussagen sollten illegal sein. Compiler sollte in beiden Fällen Fehler werfen.

Nein, sollte es nicht. Die beiden Aussagen sind völlig legal. Aufgrund der Umstände ist der erste nicht definiert. Es wäre ein Fehler, wenn sie auf const char s verweisen würden.

Soweit ich weiß, können String-Literale genauso definiert werden wie andere Literale und Konstanten. Es gibt jedoch Unterschiede:

%Vor%

Meine Verwendung von ROM und RAM hier ist allgemein. Wenn die Plattform nur RAM ist (z. B. die meisten Nintendo DS-Programme), können const-Daten im RAM sein. Schreibvorgänge sind jedoch immer noch undefiniert. Die Position von const-Daten sollte für einen normalen C ++ - Programmierer keine Rolle spielen.

    
strager 05.04.2009, 06:46
quelle
8
%Vor%

Definiert strPtr einen Zeiger auf char, der auf ein String-Literal "Hello" zeigt - der effektive Typ dieses Zeigers ist const char * . Keine Änderung durch strPtr zum Pointee erlaubt (ruft UB auf, wenn Sie dies versuchen). Dies ist eine Abwärtskompatibilität für älteren C-Code. Diese Konvention ist in C ++ 0x veraltet. Siehe Anhang C:

  

Änderung: Zeichenfolgenliterale const   Der Typ eines String-Literals wird von "array of char" in "array of const char." Geändert [...]

     

Begründung: Dadurch wird vermieden, dass eine unangemessene überladene Funktion aufgerufen wird, die möglicherweise in der Lage ist, ihr Argument zu ändern.

     

Auswirkung auf das Originalmerkmal: Wechsel zur Semantik eines gut definierten Features. Schwierigkeit der Konvertierung: Einfache syntaktische Transformation, da String-Literale in char * umgewandelt werden können; (4.2). Die häufigsten Fälle werden durch eine neue, aber veraltete Standardkonvertierung behandelt:

     

char* p = "abc"; // valid in C, deprecated in C++

     

char* q = expr ? "abc" : "de"; // valid in C, invalid in C++

     

Wie weit verbreitet: Programme, die einen legitimen Grund haben, String-Literale als Zeiger auf potentiell modifizierbaren Speicher zu behandeln, sind wahrscheinlich selten.

%Vor%

Der deklarierte Typ von strPtr ist - es ist ein Array von Zeichen unspezifizierter Größe, das die Zeichenkette Hello einschließlich des Null-Terminators, d. h. 6 Zeichen, enthält. Die Initialisierung macht es jedoch zu einem vollständigen Typ, und sein Typ besteht aus einem Array von 6 Zeichen. Änderung über strPtr ist in Ordnung.

  

Wo genau werden String-Literale gespeichert?

Implementierung definiert.

    
dirkgently 05.04.2009 06:50
quelle
1

Die älteren C- und C ++ - Compiler basierten ausschließlich auf Low-Level-Kodierung, wo höhere Datenschutzstandards nicht verfügbar waren, und sie können nicht einmal erzwungen werden, typischerweise in C und C ++ können Sie alles schreiben, was Sie wollen ..

Sie können sogar einen Code schreiben, um auf Ihre const-Zeiger zuzugreifen und diese zu ändern, wenn Sie wissen, wie man mit den Adressen spielt.

Obwohl C ++ einen gewissen Schutz auf Kompilierstufe erzwingt, gibt es keinen Schutz für die Laufzeit. Sie können sicherlich auf Ihren eigenen Stapel zugreifen und seine Werte verwenden, um alle Daten zu manipulieren, die auch in const-Zeiger enthalten sind.

Das ist der Grund, warum C # erfunden wurde, wo wenig höhere Standards durchgesetzt werden, denn was immer Sie zugreifen, ist eine Referenz, es ist eine feste Struktur, die alle Regeln des Datenschutzes beherrscht und einen versteckten Zeiger hat, auf den nicht zugegriffen werden kann / p>

Der Hauptunterschied besteht darin, dass C ++ Ihnen nur den Schutz der Kompilierzeit geben kann, aber C # wird Ihnen sogar zur Laufzeit Schutz bieten.

    
Akash Kava 05.04.2009 09:35
quelle

Tags und Links