Newsgroup: it.comp.lang.c
Titolo: [Help] Come creare un vettore di puntatori a struttura.

Firenze, 4 Luglio 1999
Salve, sono ormai diversi giorni che mi perdo in un problema per me
irrisolvibile.
Ho creato la seguente struttura:
struct Agenda
{
	long  id;
	char* szNome;
	char* szTelefono;
	char* szIndirizzo;
	char* szNote;
};
dopodiche' vorrei costruire un vettore i cui singoli elementi sono
puntatori ognuno dei quali punterebbe a una struttura di tipo "Files"
Il problema e' che il vettore dovrebbe essere allocato dinamicamente
con la malloc.
Questo perche' non so' a priori quanti elementi servirebbero.
E' ormai piu' di una settimana che provo in tutte le salse e non
riesco ad ottenere il risultato voluto, tra errori di allocazione e
valori ritornati sbagliati.
So bene che potrei risolvere il problema utilizzando una allocazione
statica con un generoso numero di elementi:
es:
struct Agenda elementi[1000];
ma questa soluzione non mi piace neanche un po'
Qualcuno saprebbe indicarmi il codice per effettuare 
questo tipo di allocazione dinamica?
Grazie infinite.

struct Agenda elementi[1000];
puoi benissimo scrivere :
typedef struct { ... } * AgendaPtr ;
...
AgendaPtr MyPtr ;
MyPtr = malloc( sizeof( *MyPtr ) * 1000 ) 
Andrea Laforgia
-----------------------------------------------------
There is nothing better for understanding a kangaroo
than seeing it jump.
-----------------------------------------------------

 Questo perche' non so' a priori quanti elementi servirebbero.
una soluzione (che potrebbe essere buona per la tua applicazione)
e' di usare una lista puntata. Cioe' alla tua struttura dovresti aggiungere
un campo aggiuntivo next:
struct Agenda
 {
 	long  id;
 	char* szNome;
 	char* szTelefono;
 	char* szIndirizzo;
 	char* szNote;
	struct Agenda *next;
 };
Adesso seguimi un po' nel ragionamento perche' se non le
conosci le liste puntate sembrano complicate (ma non lo sono
poi tanto).
Inizializzi la lista (il corrispettivo di un vettore) con:
struct Agenda *RootAgenda=NULL;
Ogni volta che vuoi inserire un nuovo elemento devi prima allocarlo e poi
inserirlo nella lista.
struct Agenda *new;
new=(struct Agenda *) malloc(sizeof(struct Agenda));
/** riempi i campi di new con quello che vuoi **/
new->next=RootAgenda;  /** queste due righe inseriscono new in testa alla lista
**/
RootAgena=new;
ovviamente questo tipo di trattazione ti permette di trattare un numero 
arbitrario di elementi appartenenti alla lista.
Ovviamente puoi migliorare le istruzioni di inserimento in modo da
ordinare come vuoi la lista, poniamo che tu abbia due elementi p e
q consecutivi e ci voglia mettere in mezzo un elemento new (tutti
e tre del tipo struct Agenda *):
new->next=q;  /** oppure p->next a tuo piacere **/
p->next=new;
Il difetto di questa e' che hai un tipo di accesso sequenziale.
se ti serve un tipo di accesso piu' veloce alla lista (cioe' se questa
diviene molto grande) devi passare agli alberi binari o agli heap che
gestiscono meglio moli anche molto grandi di dati.
Adesso che ci penso potresti anche definire un vettore
struct Agenda *new;
new=(struct Agenda *) malloc (sizeof(struct Agenda) * NElementi);
e controllare ogni volta se stai inserendo troppi elementi
nel caso puoi usare la funzione realloc che ti permette
di definire un nuovo vettore (solitamente piu' grande del doppio e questo
fatto del doppio dipende dal fatto che molti compilatore gestiscono
la memoria a potenze di due) i cui primi elementi sono gli
elementi del vecchio.
Ovviamente se segui questo metodo ricordati di porre
NElementi= NElementi * 2; 
in modo da poter continuare a controllare se devi effettuare
ancora un nuovo realloc...
buona fortuna
                             Andrea Zaghi

Andrea Laforgia
Ho provato la sintassi e funziona perfettamente !
Grazie infinite.

 };
Ti sei ricordato di allocare memoria per ognuno dei puntatori?
EMG