Programmare in C – Puntatori a puntatori

Guida C

E’ possibile e spesso utile creare puntatori a puntatori. Questa tecnica viene chiamata anche handle ed è comoda in certe situazioni quando il sistema operativo vuole mantenere la capacità di muovere blocchi di memoria nella memoria heap a sua completa discrezione.

Il seguente esempio mostra un puntatore a un puntatore.

int **p;
        int *q;

        p = (int **)malloc(sizeof(int *));
        *p = (int *)malloc(sizeof(int));
        **p = 12;
        q = *p;
        printf("%d\n", *q);
        free(q);
        free(p);

Windows e MacOS usano questa struttura per permettere di compattare la memoria utilizzata nella memoria heap. Il programma gestisce il puntatore p, mentre il sistema opeartivo gestisce il puntatore *p. Poichè è il sistema operativo che gestice *p, il blocco di memoria puntato da *p (**p) può essere spostato e quindi *p può cambiare per effetto dello spostamento, il tutto senza provocare problemi nel programma che usa p. I puntatori ai puntatori sono frequentemente utilizzati in C per gestire i puntatori a parametri nelle funzioni.

I Puntatori a strutture contenenti puntatori

E’ anche possibile creare puntatori a strutture che contengono puntatori. Il seguente esempio usa il record Addr visto nella precedente lezione.

typedef struct
        {
                char name[21];
                char city[21];
                char phone[21];
                char *comment;
        } Addr;
        Addr *s;
        char comm[100];

        s = (Addr *)malloc(sizeof(Addr));
        gets(s->name, 20);
        gets(s->city, 20);
        gets( s->phone, 20);
        gets(comm, 100);
        s->comment =
     (char *)malloc(sizeof(char[strlen(comm)+1]));
        strcpy(s->comment, comm);

Il puntatore s punta ad una struttura che contiene un puntatore che punta ad una stringa:

In questo esempio, è molto semplice “perdere” dei blocchi se non si sta molto attenti. Per esempio, ecco una diversa versione dell’esempio:

s = (Addr *)malloc(sizeof(Addr));
        gets(comm, 100);
        s->comment =
     (char *)malloc(sizeof(char[strlen(comm)+1]));
        strcpy(s->comment, comm);
        free(s);

Questo codice “perde” un blocco perchè la struttura che contiene il puntatore che punta alla stringa viene liberata prima che il blocco stringa sia liberato a sua volta:

Collegamenti tra puntatori/strutture

E’ possibile creare strutture che sono in grado di puntare ad altre strutture ad esse identiche. Questa capacità può essere usata per collegare un’intera stringa di record identici in una struttura chiamata linked list.

typedef struct
        {
                char name[21];
                char city[21];
                char state[21];
                Addr *next;
        } Addr;
        Addr *first;

Il compilatore vi permetterà di fare ciò e con un po’ di pratica si può acquisire la dimestichezza con strutture e compilatori.

STAMPA     Tags:,

Leave a Reply