2010-12-05 4 views
2

Ich drucke aus Adressen und Strings aus den folgenden zwei Deklarationen und Initialisierungen:char * variable Adresse vs. char [] variable Adresse

char * strPtr = (char *) "This is a string, made on the fly."; 
    char charArray [] = "Chars in a char array variable."; 

Wenn gedruckt wird, die folgende Ausgabe erfolgt mit extrem unterschiedlichen Adressen für die Variablen charArray und strPtr. Die Frage ist: "Warum?"

Druck:

printf("%10s%40s%20p\n", "strPtr", strPtr, &(*strPtr));  
    printf("%10s%40s%20p\n", "charArray", charArray, charArray); 

Ausgang:

strPtr  This is a string, made on the fly.   0x400880  
charArray   Chars in a char array variable.  0x7fff12d5ed30 

Die verschiedenen Adressen, wie Sie sehen, sind: 0x400880 gegen 0x7fff12d5ed30

Der Rest der deklarierte Variable, bevor diese Adressen haben wie das von CharArray.

Wieder ist die Frage: "Warum sind die Adressen so unterschiedlich?" Danke für jede Hilfe.

+4

Nur ein paar Ratschläge; Es ist vorteilhafter, Zeiger auf String-Literale zu deklarieren, zum Beispiel 'const char * str =" string ";'. Dies verhindert das undefinierte Verhalten beim Versuch, Zeichenfolgenliterale zu ändern. – dreamlax

+0

@dreamlax +1 für solide Beratung – Gemini14

Antwort

3

Ich vermute, der Compiler/Linker legt das Char-Array auf dem Stapel, während der andere String in eine statische String-Tabelle gelegt wird.

4

Weil Zeichenkettenliterale, z.B. "foo bar" wird an einer "anderen Stelle" zugewiesen als Ihr char-Array.

Dies ist Implementierung abhängig, aber eine typische Implementierung wird Stringliterale in Ihrem .rdata („read-only-Daten“) Abschnitt ausführbare Datei setzen, und Ihr char-Array lokal erklärt und geht daher auf dem Stapel.

Und verschiedene Abschnitte Ihres Bildes werden zu sehr unterschiedlichen Adressen zugeordnet, wenn sie in RAM geladen werden.

2

Der Text "Zeichen in einer Char-Array-Variable." und "Dies ist eine Schnur, im Handumdrehen gemacht." sind wahrscheinlich ziemlich nahe beieinander. char charArray[] = ... fordert jedoch Speicherplatz auf dem Stapel an, in den das entsprechende Bit des Texts kopiert wird. Der Stapel ist praktisch in einem anderen Universum als der ursprüngliche fest codierte Text, sobald das Betriebssystem mit seiner Virtualisierung usw. fertig ist.

2

So geht es - ich erinnere mich, darüber gelesen zu haben in [Unix: Systems Programming]

1alt text

wie Sie statische Daten Initialized sehen wird an einer anderen Stelle auf dem Heap nicht initialisierte statische Daten im Gegensatz gespeichert.

1

Entscheidend ist hier zu erkennen ist, dass im Fall von strPtr, mit Ihnen nur einemzwei verschiedenen Objekten, während im Fall von charArray, Sie sich zu tun zu tun.

charArray ist ein einzelnes Array-Objekt, gefüllt mit den Zeichen der "Chars in a char array variable." Zeichenfolge.

strPtr selbst ist ein einzelnes Zeigerobjekt. Ihr Wert ist die Adresse eines zweiten anonymen, nicht änderbaren Array-Objekts, das wiederum die Zeichen der Zeichenfolge enthält.Wenn Sie charArray mit %p ausdrucken, drucken Sie die Adresse charArray[0] (aufgrund einer speziellen Regel für Arrays). Wenn Sie &(*strPtr) (das ist genau das gleiche wie nur strPtr) ausdrucken, drucken Sie die Adresse des oben erwähnten anonymen, nicht änderbaren Array-Objekts - und deshalb erscheint es so anders als die Adressen der anderen beteiligten Variablen. Wenn Sie &strPtr mit %p ausdrucken, sehen Sie, dass die Adresse der Variablen strPtr selbst in einem ähnlichen Bereich wie die anderen lokalen Variablen liegt.