Referenzen auf String Literale und wiedermal char* = ...
-
KasF schrieb:
Hier existiert doch die Speicherstelle, in der "Hallo" steht, solange wie auch p existiert.
Seit wann haben Literale Referenzzählung oder Pointer einen Mechanismus dafür?

Das Literal existiert während der gesamten Programmlaufzeit, die Adresse davon solange, bis Du sie verlierst.
EDIT:
Zur Klärung: Das Literal "Hallo" wird vom Compiler "irgendwo" hingeschoben und die Adresse von "irgendwo" an der Stelle des Literals eingesetzt. Wieso sollte das Ergebnis dessen (oder gar die Lebensdauer vom Literal) bei einer Initialisierung anders sein als bei einer Zuweisung?
-
LordJaxom schrieb:
Seit wann haben Literale Referenzzählung oder Pointer einen Mechanismus dafür?

Temporäre Objekte existieren auch, solange der Ausdruck nicht abgearbeitet ist, zB bei der Übergabe eines temp-Objektes an eine Funktion, aber brauche ich dir ja nicht alles zu erklären

Ich werd noch wahnsinnig, diese Literal-Geschichte macht mich noch ganz vErÜcKT.
Ich glaube ich lasse das dann mal und nehme einige Sachen mal erstmals so hin ...
-
Temporäre Objekte werden aber an Referenzen gebunden - hier hast Du eine einfache Wertzuweisung einer Adresse an einen Zeiger - sprich der Wert des Zeigers wird kopiert.
Wichtig ist eigentlich nur, dass Literale in einem Bereich unendlicher Lebensdauer liegen, und dass der Compiler ihr Vorkommen durch eine Adresse ersetzt (wobei nicht definiert ist, ob Literale identischen Inhalts auch identische Adressen haben müssen). Damit ist folgendes technisch identisch:
char* x = 0x123456; x = 0x654321; int y = 12; y = 24;
-
LordJaxom schrieb:
Wichtig ist eigentlich nur, dass Literale in einem Bereich unendlicher Lebensdauer liegen, und dass der Compiler ihr Vorkommen durch eine Adresse ersetzt (wobei nicht definiert ist, ob Literale identischen Inhalts auch identische Adressen haben müssen).
Das gilt aber nur für String-Literale, oder? Für andere wird doch keinen Speicher alloziert...
-
Ok, danke und was ist hiermit, ist dies wohldefiniert und gültig:
char *p; p = "Hallo";Denn normal würde man das hier doch so machen:
char p[10]; strcpy(p, "Hallo"); // oder char *p = new char[10]; strcpy(p, "Hallo"); delete [] p;
-
Nexus schrieb:
Das gilt aber nur für String-Literale, oder? Für andere wird doch keinen Speicher alloziert...
Was für "andere"? Meinst Du Arrays? Sprich:
char x[] = "Hallo"; // x == Array von 6 Bytes auf Stack mit Inhalt 'H', 'a', ... char* y = "Hallo"; // y == Zeiger auf Stack mit Inhalt "Adresse von Literal Hallo im Readonly-Speicher"Im ersten Fall werden sechs Bytes auf dem Stack benötigt, im zweiten sizeof(void*) auf dem Stack und 6 in dem Bereich, in dem der Compiler Literale ablegt.
@KasF
KasF schrieb:
Ok, danke und was ist hiermit, ist dies wohldefiniert und gültig:
Ich glaube, hier ist irgendwo ein Verständnisproblem oder ein kleines Brett vorhanden

Hier passiert:
Datenbereich des Programms: 0x01000 H a l l o \0 0x01006 W e l t \0 Funktion des Programms: [Pseudocode] add ebp, 4 // 4 Byte auf Stack reservieren (hieß mal "p") mov [ebp+0], 0x01000 // auf "p" die Adresse von "Hallo" schreiben .... mov [ebp+0], 0x01006 // auf "p" die Adresse von "Welt" schreibenIch weiss nicht, wie ich sonst darstellen soll, dass es sich bei Literalen um Daten, die unbegrenzte Lebenszeit während der Programmlaufzeit haben, handelt, und die Adressen dieser Daten lediglich im Programm "herumgeschubst" werden.
-
LordJaxom schrieb:
Ich weiss nicht, wie ich sonst darstellen soll, dass es sich bei Literalen um Daten, die unbegrenzte Lebenszeit während der Programmlaufzeit haben, handelt, und die Adressen dieser Daten lediglich im Programm "herumgeschubst" werden.
Hmm... vielleicht so:
Wenn du ein String-Literal benutzt, wird für dich ein globale Konstante angelegt.int main() { const char* p = "Hello World!"; }Ist also (in etwa) identisch zu:
const char Literal_Hello_World[] = "Hello World!"; int main() { const char* p = Literal_Hello_World; }Deshalb kann man z.B. String-Literale aus Funktionen zurückgeben, ohne undefiniertes Verhalten hervorzurufen.
Gruß
Don06
-
LordJaxom schrieb:
Nexus schrieb:
Das gilt aber nur für String-Literale, oder? Für andere wird doch keinen Speicher alloziert...
Was für "andere"? Meinst Du Arrays?
Nein, ich meinte Non-String-Literale wie
43.7foder208, für die ja kein Speicher reserviert wird. Aber darum scheint es eh nicht zu gehen, es war mir nur aus deinem Post nicht ganz klar, ob du allgemein Literale meintest.Wenn man das selbe String-Literal mehrmals benutzt, wird jedes Mal Speicher reserviert, oder?
Also abgesehen von der Sinnlosigkeit:std::cout << "Hello World" << std::endl; std::string Str = "Hello World";
-
Wobei ich nicht verstehe wieso man das machen kann.
char* text = "hallo"; text[0] = 'B'; //kracht natürlichAus Kompatibilitätsgründen nehme ich an, oder?
-
@Nexus:
Das ist wie gesagt nicht definiert (dem Compiler überlassen), beim MSVC kannst Du z.B. "String Pooling" einschalten, wobei hier für mehrere separate aber inhaltlich identische Literale nur einmal Speicherplatz reserviert wird.
-
LordJaxom schrieb:
kleines Brett vorhanden
Brett von LordJaxom durchgeschlagen.

templäd schrieb:
Wobei ich nicht verstehe wieso man das machen kann.
char* text = "hallo"; text[0] = 'B'; //kracht natürlichAus Kompatibilitätsgründen nehme ich an, oder?
text ist halt nen einfaches char* und da ist text[0] = ... bzw *(text+0) = ... auch ja ganz normal und hat hier nichts mit Kompatibilität zu tun.