2009-11-20 5 views
14

Así que tengo el siguiente programa:Segmentation Fault Con Char matriz y puntero en C en Linux

int main(){ 
    char* one = "computer"; 
    char two[] = "another"; 
    two[1]='b'; 
    one[1]='b'; 
    return 0; 
} 

Se segfaults en la línea de "uno [1] = 'B'", lo cual tiene sentido porque la memoria que el puntero "uno" señala que debe estar en la memoria de solo lectura. Sin embargo, la pregunta es por qué la línea "dos [1] = 'b'" no falla? En cuanto a la salida de montaje de gcc:

.file "one.c" 
     .section  .rodata 
.LC0: 
     .string "computer" 
.LC1: 
     .string "another" 
     .text 
.globl main 
     .type main, @function 
main: 

vemos que ambas cadenas están en la sección Rodata por lo que son de sólo lectura. De manera que ¿cómo es que la línea de "dos [1] = 'B' no segfault?

+0

Véase también la pregunta diferente pero relacionado http://stackoverflow.com/questions/ 1770062/defining-pointer-to-static-string/1770067 # 1770067 –

Respuesta

35

one puntos directamente a la cadena se encuentra en una página de sólo lectura. Por otro lado, two es una serie asignado en la pila y se inicializa con algunos datos constantes. En el tiempo de ejecución, la cadena en la sección de solo lectura del ejecutable se copiará a la pila. Lo que está modificando es la copia de esa cadena en la pila, no la página de memoria de solo lectura .

en una perspectiva de nivel más alto, desde el punto de vista del lenguaje, "abcd" es una expresión de tipo const char* y no char*. por lo tanto, la modificación del valor señalado por tales expresión un resultado en un comportamiento indefinido. la declaración char* one = "something"; simplemente almacena el puntero a la cadena en una variable (inseguro, ya que está descartando el modificador const). El char two[] = "something"; es totalmente diferente. De hecho, está declarando una matriz e inicializándola, al igual que int a[] = {1,2,3};. La cadena entre comillas aquí es la expresión de inicialización.

+3

Wow ... He estado programando en C desde hace aproximadamente 5 años y no sabía que 'char []' hizo una copia de datos constantes. Siempre pensé que '[]' era solo una forma más elegante de escribir '*'. ¡Gracias! +1 – Earlz

+3

A menudo escribo 'char str [] = {" Something "};' en un intento de aclarar la asociación. – LnxPrgr3

+0

@ Mehrdad: ¡Claro como el cristal! :) –

1

El "otro" que ve en la sección rodata es lo que se copiará en la matriz two cuando se inicialice. Por otro lado, la dirección de la cadena "computadora" se asignará a una.

Por lo tanto, one apunta a un segmento de solo lectura (y de ahí el segfault en escritura) mientras que two se asignará en la pila y luego se copiará "otro" en él.

0

El segundo formulario crea una matriz copiando la cadena literal.

Es equivalente a:

char two[] = {'a', 'n', 'o', 't', 'h'. 'e', r', '\0'}; 

Puede inicializar una matriz de caracteres con las variables, tales como

char c = 'a'; 
char two[] = {'a', 'n', c, '\0'}; 
Cuestiones relacionadas