2012-06-06 15 views
8

Quando provo la seconda opzione nel seguente codice per inizializzare names, ottengo un errore di segmentazione. Immagino ci sia qualcosa di concettualmente scorretto con la seconda opzione. Qualche idea?Perché non si può usare un puntatore a puntatori di carattere anziché una serie di puntatori di caratteri?

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

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

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

+0

Forse dirci PERCHÉ sei così in **. Hanno poco uso oltre al ritorno dalle funzioni tramite argomenti. –

+0

@Agent_L Stavo seguendo il libro "Learn C The Hard Way" (http://c.learncodethehardway.org/book/learn-c-the-hard-waych16.html), dove c'è un esercizio su "Riscrivi" tutto l'uso dell'array in questo programma in modo che sia puntato. " –

risposta

6

Sì. Nel primo caso, hai una serie di puntatori. Ogni puntatore punta a un elemento separato (Alan, Frank ...)

La seconda dichiarazione

char **names; 

implica che i nomi è un puntatore a un puntatore [Non è possibile inizializzare un insieme di stringhe come questo]. Come in

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

Ha un layout di memoria completamente diverso.

Il primo esempio è un array di puntatori. Occupa 5 volte la dimensione di un char *.

Il secondo esempio, tuttavia, è un puntatore a una posizione in cui uno o più char * sono previsti. Non è possibile inizializzarlo nel modo in cui lo fai.

+0

Grazie, quale sarebbe il modo corretto di inizializzare per la seconda opzione –

+2

Il primo modo è il modo corretto. char ** i nomi non sono un array. È un puntatore a un puntatore e quindi può contenere l'indirizzo di un puntatore come avevo postato sopra. –

+0

@stressed_geek Puoi avere un punto 'char **' (2nd way) su un array (1a via). Ma prima, devi inizializzarlo. 'char * names [] = {...}; char ** n2 = &names; 'potrebbe essere un modo per andare ... – glglgl

2

Nel primo caso si dispone di un array di char*. Ciò significa che è stata allocata memoria per 5 variabili * char (le voci dell'array), ordinatamente in memoria una dopo l'altra. Inoltre, ognuno di essi viene inizializzato all'inizio di ogni stringa.

Nel secondo caso, si dispone di un puntatore di tipo char **. Hai solo una memoria sufficiente per un puntatore.

(ho saltato discutere la memoria allocata per ogni stringa. Può essere lo stesso in entrambi i casi, ma è irrilevante qui)

0

Non causare un guasto seg con gcc. Tuttavia tentare lo stesso questo con una matrice intera potrebbe illustrare il motivo per cui non ha molto senso:

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)); 

La cosa strana è che questo esempio produce in realtà i risultati attesi per l'array intero. Tuttavia gcc produce un avvertimento.

Problemi correlati