[C] File binari e strutture dati dinamiche

Atem1
Salve ragazzi, avrei una domanda su quale sia il miglior metodo per leggere da file binario e memorizzare i dati letti in una struttura dinamica. Io faccio così, ma mi sembra un pò ridondante:
typedef struct
{
    int id;
    char stringa[MAXCHARS];
} t_coppie;


typedef struct node *link;
struct node
{
    int id;
    char *stringa;
    link next;
};



link storeList(FILE *fp, link head)
{
    t_coppie coppie;
    link p;
    while (fread(&coppie, sizeof(coppie), 1, fp)>0)
    {
        p=malloc(sizeof(*p));
        p->id=coppie.id;
        p->stringa=malloc(1+strlen(coppie.stringa));
        strcpy(p->stringa, coppie.stringa);
        p->next=NULL;
        head=insertTail(head, p);
    }
    return head;

}



Insomma quello che intendo dire è che non mi piace tanto aver dovuto definire due tipi praticamente uguali.
Si può ottimizzare in qualche modo la cosa? O va bene così?
Grazie mille per l'attenzione :)

Risposte
Atem1
A proposito, un'altra cosa su cui sono perplesso è il fatto di aver dovuto dichiarare il campo "stringa" come array statico di char in un typedef e come puntatore a char nell'altro.
Il motivo è che, nella creazione del file, ho usato stringa[MAXCHARS] perchè altrimenti invece di salvare la stringa, la fwrite salvava il puntatore e naturalmente esso restava valido finchè usavo la free o finchè non chiudevo il programma. Dopo di che alla riapertura del programma chiaramente quel puntatore andava a puntare qualcosa che non aveva niente a che fare con le stringhe a cui era stato inizialmente assegnato. Quindi mi chiedo, se il codice che ho scritto sopra va migliorato, oppure se la cosa migliore è restare sul semplice e lasciare le cose come stanno visto che funziona?

archetipo1
Credo che sia difficile da una porzione di programma capire se il codice sia buono o meno, ci sono mille ragioni per definire due tipi simili come ce ne sono mille per non farlo... a quanto si vede dal ciclo di lettura il puntatore p viene utilizzato da una funzione.
E' chiaro che tutti gli indirizzi di memoria del programma esistono solo ed esclusivamente nel ciclo di vita del programma stesso, quindi è normale che quando si chiude il programma gli indirizzi siano assegnati ad altre istanze. Quando si riapre il programma viene eseguita una nuova ri-allocazione della memoria tutta.
comunque una soluzione per definire un struttura più compatta potrebbe essere:
typedef struct node *link;
struct node
{
    int id;
    char *stringa;
    link next;
};

typedef struct
{
    link p;
    char stringa[MAXCHARS];
} t_coppie;


in questo modo la struct t_coppie contiene un membro node, ma dato che non è chiaro cosa faccia il programma se questo sia un buon modo.
saluti

apatriarca
Il migliore metodo per leggere da file binario e inserire i valori in un qualche tipo di struttura dati è ovviamente quello di memorizzare la struttura dati così com'è in memoria. Questo non è però possibile farlo quando si usano puntatori ed è quindi necessario rimediare in qualche modo. Le soluzione possibili sono principalmente le seguenti:
1. Modificare la struttura dati in memoria in modo da usare indici al posto di puntatori.
2. Modificare i "puntatori" durante la scrittura su file in modo che contengano la posizione della corrispondente struttura nel file. Dopo aver letto il file intero in memoria è però poi necessario iterare su tutta la struttura per correggere tutti i puntatori in modo che contengano il corretto indirizzo di memoria (normalmente si tratta semplicemente di aggiungere a tutti i puntatori l'indirizzo al blocco allocato per inserire la struttura).
3. Fare come hai fatto.
Di tutte le possibili soluzioni la prima è la più desiderabile quando possibile. La seconda potrebbe apparire complicata ma è un metodo molto flessibile e permette di caricare praticamente qualsiasi tipo di struttura senza problemi (fanno ovviamente eccezioni strutture che contengono riferimenti a file o altre cose simili..).

Atem1
Ok vi ringrazio tantissimo per tutto l'aiuto che mi avete dato :)
Io ho fatto l'esame il 30 Agosto, oggi sono usciti i voti e ho preso 30.
L'esame si basava su una struttura "albero di liste".
Ringrazio tutti quelli che mi hanno aiutato ma evitando di fare la lista perchè potrei dimenticare qualcuno :)

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.