2012-06-06 9 views
8

Cuando intento la segunda opción en el siguiente código para inicializar names, aparece un error de segmentación. Supongo que hay algo conceptualmente incorrecto con la segunda opción. ¿Algunas ideas?¿Por qué no se puede usar un puntero a punteros de char en lugar de una matriz de punteros de char?

char *names[] = { 
      "Alan", "Frank", 
      "Mary", "John", "Lisa" 
     }; 

char **names = { 
      "Alan", "Frank", 
      "Mary", "John", "Lisa" 
     }; 
+0

'char name [] =" Allan ";' 'char ** names = &name;' –

+0

Quizás nos diga POR QUÉ usted está tan metido en **. Tienen poco uso además de regresar de las funciones a través de argumentos. –

+0

@Agent_L Estaba siguiendo el libro "Aprende C de la manera difícil" (http://c.learncodethehardway.org/book/learn-c-the-hard-waych16.html), donde hay un ejercicio para "Reescribir todo el uso de la matriz en este programa para que sean punteros ". –

Respuesta

6

Sí. En el primer caso, tiene una serie de punteros. Cada puntero apunta a un tema separado (Alan, Frank ...)

La segunda declaración

char **names; 

implica que los nombres es un puntero a un puntero [No se puede inicializar un conjunto de cadenas como este]. Como en

char *str = "hello" 
char **names = &str; 
2

Tiene un diseño de memoria completamente diferente.

Su primer ejemplo es una serie de punteros. Ocupa 5 veces el tamaño de char *.

Su segundo ejemplo, sin embargo, es un puntero a una ubicación donde se esperan uno o más char *. No es posible inicializarlo de la manera en que lo haces.

+0

Gracias, ¿cuál sería la forma correcta de inicializar para la segunda opción? –

+2

La primera forma es la correcta. char ** names no es una matriz. Es un puntero a un puntero y, por lo tanto, puede contener la dirección de un puntero tal como lo había publicado anteriormente. –

+0

@stressed_geek Puede hacer que un punto 'char **' (2nd way) apunte a una matriz (1ra manera). Pero primero, debes inicializarlo. 'char * names [] = {...}; char ** n2 = &names; 'podría ser un camino por recorrer ... – glglgl

2

En el primer caso, tiene una matriz de char*. Esto significa que ha asignado memoria para 5 variables de caracteres * (las entradas de la matriz), ordenadamente colocada en la memoria una detrás de la otra. Además, cada uno de ellos se inicializa al comienzo de cada cadena.

En el segundo caso, tiene UN puntero de tipo char **. Solo tiene suficiente memoria para un puntero.

(he omitido hablar de la memoria asignada para cada cadena. Puede ser el mismo en ambos casos, pero es irrelevante aquí)

0

No causar una falla seg con gcc. Sin embargo intentar la misma esto con una matriz de enteros, posiblemente, podría ilustrar por qué no tiene mucho sentido:

char* names[] = { "Dennis", "Richie" }; 
char** more_names = { "Sarah", "O'connor" }; 

printf("Name: %s %s\n", names[0], names[1]); 
printf("Name: %s %s\n", more_names + 0, more_names + 1); 

int numbers[] = { 0, 1 }; 
int x = 2, y = 3; 
int* more_numbers = { &x, &y }; 

printf("Numbers: %d, %d\n", numbers[0], numbers[1]); 
printf("Numbers: %d, %d\n", *(more_numbers + 0), *(more_numbers + 1)); 

Lo extraño es que este ejemplo realmente produce los resultados esperados para el arreglo de enteros. Sin embargo, gcc produce una advertencia.

Cuestiones relacionadas