2011-08-16 27 views
6

Esta es una cuestión sobre la base de las respuestas de la pregunta:Char Matriz VS Char *

const char myVar* vs. const char myVar[]

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

entiendo la diferencia ahora, pero mis nuevas preguntas son:

(1) ¿Qué pasa a la cadena "Hola mundo" en la primera línea si reasigno x? Nada lo señalará en ese punto: ¿se destruiría cuando finalizara el alcance?

(2) Aparte de la const-ness, ¿cómo se almacenan los valores en los dos ejemplos en la memoria del compilador?

Respuesta

9

Al colocar "Hello World!" en el código, el compilador incluye esa cadena en el ejecutable compilado. Cuando se ejecuta el programa, esa cadena se crea en la memoria antes de llamar a main y, creo, incluso antes de la llamada de ensamblaje al __start (que es cuando comienzan a ejecutarse los inicializadores estáticos). Los contenidos de char * x no se asignan usando new o malloc, o en el marco de la pila de main, y por lo tanto no se pueden asignar.

Sin embargo, un char x[20] = "Hello World" declarado dentro de una función o método se asigna a la pila, y mientras esté en el alcance, en realidad habrá dos copias de esa "Hello World" en memoria, una precargada con el ejecutable, una en la pila buffer asignado.

+0

const char x [] se supone que copia los datos a la pila. –

-1
  1. formalmente en ambos casos la cadena "Hello World!" se asigna en la memoria estática como una secuencia contigua de char, por lo que es la memoria no asignada dinámicamente para reclamar ni ninguna instancia de clase para destruir;
  2. Ambos x s se asignarán en la memoria estática o en la pila, dependiendo de dónde estén definidos. Sin embargo, el puntero se inicializará para apuntar a la cadena correspondiente "Hello World!", mientras que la matriz se inicializará copiando directamente el literal de la cadena.

En teoría, el compilador es libre de reclamar la memoria de ambos literales de cadena cuando no hay formas de acceder a ellos; en la práctica, es poco probable que se reclame el primero, ya que normalmente la memoria estática permanece asignada al programa hasta su finalización; por otro lado, si la matriz está asignada en la pila, la segunda podría no estar asignada, ya que el compilador puede usar otros medios para asegurarse de que la matriz se inicialice correctamente, y la memoria de la matriz se recuperará cuando se apague. alcance.

+0

Además de esto, hacer sizeof (x) con el puntero dará como resultado 4 (u 8 en código de 64 bits), mientras que sizeof (x) con la matriz dará como resultado el número de bytes que contiene la matriz. – Matthew

+2

-1: No están asignados de la misma manera. El primer ejemplo es un puntero a la memoria estática. El segundo ejemplo es una matriz no estática cuyos contenidos se inicializan con '" Hello world! "'. –

+2

Creo que la idea detrás de const char x [] es que la matriz está en la pila, no simplemente un puntero, y "¡Hola mundo!" se copia a ella.Esto puede optimizarse, pero la idea es bastante diferente de un simple puntero. –

4

El compilador almacena el primero en una sección de la memoria llamada RODATA (datos de solo lectura). Mientras el programa todavía se esté ejecutando, la memoria aún conserva su valor inicial.

El segundo se almacena como cualquier otro conjunto: en la pila. Al igual que cualquier otra variable local, podría sobrescribirse una vez que finalice su alcance.

+0

'Mientras el programa se esté ejecutando, la memoria aún conserva su valor inicial. Es decir, el alcance de la cadena es el alcance del programa, no el de la función. –