2017-11-08 1 views
1

In dem obigen Code denke ich, dass der Speicher für das String-Literal in einem globalen Raum zugeordnet ist. In welchem ​​Abschnitt geht es tatsächlich und wann? Geht der Compiler durch und weist ihn im Programmbereich zu ?? Auch wenn ich eine andere Zeichenfolge mit dem gleichen Zeichenfolgenliteral, d. H. (char *k = "here";), initialisiere, wird es auf den gleichen Speicherort zeigen. Ich versuche zu denken, da ich diesen Ort nicht freigeben kann, stoße ich in irgendwelche Schwierigkeiten, wenn ich viele String-Initialisierungen in meinem Code habe. Ich denke, das Einzige, worüber ich mir Sorgen machen sollte, ist die Compilerausgabe, die zu groß ist, da in diesem Fall keine Laufzeitspeicherzuweisung vorhanden ist?Speicherzuordnung von String literal strcpy

+3

Die wörtliche zugeordnet ist in '. Rodata'. Oder gar nicht zugewiesen, da es eine kurze Zeichenfolge ist und in Register passen kann. Aber Ihr Code ist sowieso ungültig. Da 's' nicht zugewiesen ist. –

Antwort

3

Die genaue Position hängt vom Objektdateiformat ab (PE vs. ELF vs. COFF) und allen Befehlszeilenoptionen (einige können Zeichenfolgenliterale in einem beschreibbaren Speichersegment speichern). ELF speichert es im Segment .rodata, das, wie der Name sagt, schreibgeschützt ist.

mehrere Instanzen des gleichen Stringliteral kann Karte an den gleichen Ort, aber es ist nicht erforderlich AFAIK (Ich bin nicht bekannt, dass Compiler, mehrere Instanzen des gleichen wörtlichen, aber meine Erfahrung ist das nicht schafft breit).

Dinge, die sicher sind:

  • Raum für Stringliterale wird beim Programmstart zugewiesen (in der Regel, wenn das Programm in den Speicher geladen wird), und gehalten, bis das Programm beendet;
  • Der Versuch, den Inhalt eines Stringliteral Invokes zu ändern undefinierten Verhalten - Code kann segfault, oder es kann wie vorgesehen funktionieren, oder es kann die Festplatte formatieren, oder es kann die Zombie-Apokalypse auslösen.

Beachten Sie, dass der Code einen Fehler hat - man kann nie eine sinnvolle Adresse s zuweisen, so dass die strcpy im Wesentlichen versucht, die Zeichenfolge "here" an einen zufälligen Ort zu schreiben, die wiederum nicht definiertes Verhalten ist. Sie haben vielleicht

s = "here"; 

schreiben wollte, die s zu wörtlichen Punkt setzt. Wenn nicht, dann wird s entweder ein Array groß genug sein, um die Zeichenfolge zu halten:

char s[sizeof "here"]; // sizeof evaluated at compile time 

oder Sie werden dynamisch, dass der Raum zuweisen müssen:

char *s = malloc(strlen("here") + 1); 
if (s) 
    strcpy(s, "here");