Ciao a tutti,
stavo sperimentando un po' gli array di puntatori. Per intenderci qualcosa del genere:
char *lista[2];
Credo di intuire il problema, ma ho bisogno di una conferma o di una smentita e come nel ovviare a quello che sto cercando di seprimentare.
Prima di arrivare al punto cruciale esporrò un'analogia con un esempio che si potrebbe dire un po' "rovesciato" rispetto a quello in questione. Utilizzo come primo esempio i parametri ricevuti dalla funzione main. E leggo i parametri passati leggendo carattere, per carattere attraverso l'aritmetica dei puntatori e tutto funziona secondo quanto previsto:
#include <stdio.h>
int main(int argc, char *argv[])
{
if(argc == 1)
{
int colonna = 0;
while(*(*(argv) + colonna) != '\0')
{
printf("%c",*(*(argv) + colonna));
colonna++;
}
printf("\n");
}
else
{
int colonna = 0;
for(int i=0;i<argc;i++)
{
colonna = 0;
while(*(*(argv + i) + colonna) != '\0')
{
printf("%c",*(*(argv + i) + colonna));
colonna++;
}
printf(" ");
}
printf("\n");
}
return 0;
}
Quindi come al solito posso scorrere le "righe" dell'array incrementando la sua locazione tanti quanti sono i parametri passati (argv+i). Ovviamente ogni incremento di "i" è la locazione di memoria ove è salvato un secondo puntatore. Dunque per recuperare il puntatore alla iesima posizione effettuerò: *(argv+i). Essendo anche questo un puntatore posso a questo punto muovermi lungo le locazioni (colonne) utilizzando tale aritmetica: *(argv + i)+colonna. Ovviamente rappresenta una successione di locazioni di memoria, pertanto se voglio visualizzare il contenuto di ciascuno utilizzero ancora l'operatore di deferenza. Pertanto avrò:
printf("%c",*(*(argv + i) + colonna));
Adesso vengo al dunque del mio problema. Supponiamo di dichiarare il seguente array di puntatori:
char *line[2];
E di volerlo popolare. Intuisco che l'approccio che sto per presentare non può essere corretto, ma ottengo un risultato parzialmente inatteso, del quale vorrei comprendere il motivo.
Primo esempio
funzionante
#include <stdio.h>
int main(int argc, char *argv[])
{
char *line[2];
/** Valorizzo l'indice uno */
*(*(line+0)+0) = 'P';
*(*(line+0)+1) = 'l';
*(*(line+0)+2) = 'u';
*(*(line+0)+3) = 't';
*(*(line+0)+4) = 'o';
*(*(line+0)+5) = '\0';
printf("%s\n",line[0]); /** Stampo la stringa del primo puntatore utilizzando gli indici dei vettori */
/** Stampo la stringa del primo puntatore utilizzando l'aritmetica dei puntatori */
printf("%c%c%c%c%c%c\n",*(*(line+0)+0),*(*(line+0)+1),*(*(line+0)+2),*(*(line+0)+3),*(*(line+0)+4), *(*(line+0)+5));
return 0;
}
Adesso espongo il secondo caso (tento di valorizzare l'indice 2 del vettore di puntatori.
#include <stdio.h>
int main(int argc, char *argv[])
{
char *line[2];
*(*(line+0)+0) = 'P';
*(*(line+0)+1) = 'l';
*(*(line+0)+2) = 'u';
*(*(line+0)+3) = 't';
*(*(line+0)+4) = 'o';
*(*(line+0)+5) = '\0';
*(*(line+1)+0) = 'V';
*(*(line+1)+1) = 'a';
*(*(line+1)+2) = 'l';
*(*(line+1)+3) = 'e';
*(*(line+1)+4) = '\0';
printf("%s\n",line[0]);
printf("%c%c%c%c%c%c\n",*(*(line+0)+0),*(*(line+0)+1),*(*(line+0)+2),*(*(line+0)+3),*(*(line+0)+4), *(*(line+0)+5));
printf("============================\n");
printf("%s\n",line[1]);
printf("%c%c%c%c%c%c\n",*(*(line+1)+0),*(*(line+1)+1),*(*(line+1)+2),*(*(line+1)+3),*(*(line+1)+4));
return 0;
}
Come si potrà notare il frammento va in
Segmentation fault quando cerco di valorizzare i "puntatore" nell'indice dell'array di puntatori. Quello che ipotizzo che l'indice 1 dell'array punti a una locazione di memoria "nulla", ma perché l'indice 0 no?
Per fugare questo dubbio eseguo il seguente codice:
#include <stdio.h>
int main()
{
char *line[2];
printf("%x\n", *line);
printf("%x\n", *(line+1));
return 0;
}
E in effetti ottengo un risultato del genere:
da602250
0
Quindi l'indice 1 dell'array punta un puntatore "nullo". Può tornarmi, ma perché il primo indice contiene un puntatore inizializzato?
In realtà questo codice dovrebbe essere effettuato con allocazione dinamica?
Grazie per la pazienza e per le vostre considerazioni e insegnamenti.
Un saluto a tutti.