2011-08-16 6 views
6

Questa è una domanda in base alle risposte da domanda:Char Array VS Char *

const char myVar* vs. const char myVar[]

const char* x = "Hello World!"; 
const char x[] = "Hello World!"; 

capisco la differenza ora, ma le mie nuove domande sono:

(1) Cosa succede alla stringa "Hello World" nella prima riga se riassegniamo x? A quel punto, nulla lo indicherà: verrebbe distrutto al termine dell'ambito?

(2) A parte la costanza, in che modo i valori nei due esempi sono memorizzati in modo diverso nella memoria dal compilatore?

risposta

9

Inserendo "Hello World!" nel codice, il compilatore include tale stringa nell'eseguibile compilato. Quando il programma viene eseguito, tale stringa viene creata in memoria prima della chiamata a main e, credo, anche prima dell'assembly chiamata a __start (che è quando vengono avviati gli inizializzatori statici). I contenuti di char * x non sono allocati utilizzando new o malloc o nel frame di stack di main e pertanto non possono essere allocati.

Tuttavia, un char x[20] = "Hello World" dichiarato all'interno di una funzione o metodo viene allocato nello stack e, mentre in ambito, ci saranno in realtà due copie di quello "Hello World" in memoria - uno precaricato con l'eseguibile, uno nello stack- buffer assegnato

+0

const char x [] dovrebbe copiare i dati nello stack. –

-1
  1. Formalmente in entrambi i casi la stringa "Hello World!" è allocato nella memoria statica come una sequenza contigua di char, quindi non c'è alcuna memoria allocata dinamicamente per recuperare né istanza di classe di distruggere;
  2. Entrambi i numeri x verranno allocati nella memoria statica o in pila, a seconda di dove sono definiti. Tuttavia, il puntatore verrà inizializzato in modo da puntare alla stringa "Hello World!" corrispondente, mentre l'array verrà inizializzato copiando direttamente la stringa letterale.

In teoria il compilatore è libero di recuperare la memoria di entrambi i letterali stringa quando non ci sono modi per accedervi; in pratica è improbabile che il primo venga recuperato, in quanto di solito la memoria statica rimane assegnata al programma fino alla sua cessazione; d'altra parte se l'array è allocato nello stack, il secondo potrebbe non essere affatto assegnato, in quanto il compilatore può usare altri mezzi per assicurarsi che l'array sia inizializzato correttamente e la memoria dell'array verrà recuperata quando uscirà scopo.

+0

In aggiunta a ciò, facendo sizeof (x) con il puntatore si otterrà 4 (o 8 in codice a 64 bit), mentre sizeof (x) con l'array comporterà il numero di byte che la matrice contiene. – Matthew

+2

-1: non vengono assegnati nello stesso modo. Il primo esempio è un puntatore alla memoria statica. Il secondo esempio è un array non statico il cui contenuto è inizializzato con "Hello world!". –

+2

Penso che l'idea dietro const char x [] sia che l'array è in pila, non semplicemente un puntatore, e "Hello World!" è copiato in esso.Questo può essere ottimizzato, ma l'idea è molto diversa da un semplice puntatore. –

4

Il compilatore memorizza il primo in una sezione di memoria chiamata RODATA (dati di sola lettura). Finché il programma è ancora in esecuzione, la memoria conserva ancora il suo valore iniziale.

Il secondo è memorizzato come qualsiasi altro array: in pila. Proprio come qualsiasi altra variabile locale, potrebbe essere sovrascritta una volta terminato il suo ambito.

+0

'Finché il programma è ancora in esecuzione, la memoria conserva ancora il suo valore iniziale. Vale a dire, l'ambito della stringa è l'ambito del programma, non quello della funzione. –