Visto che è andata bene, proviamo con un array bidimensionale
Ora, per la gioia di Eugenio, proviamo ad applicare l'allocazione dinamica
della memoria ad un array bidimensionale.
Se ci pensate bene, una matrice bidimensionale altro non è che un array
monodimensionale le cui componenti altro non sono che array monodimensionali;
ovvero possiamo rappresentarla dinamicamente come un puntatore ad un array
di puntatori; possiamo anche riutilizzare le funzioni scritte per lÆarray
monodimensionale.
void main(void)
{
char ** dinamicmatrice;
unsigned int dimensioni[2] = {6, 12};
dinamicmatrice = AllocazioneMatrice(dimensioni, sizeof(char *));
if(!dinamicmatrice)
return;
/* allocazione dinamica di una matrice di 6 righe, ciascuna riga */
/* di 12 caratteri */
RiempiMatrice(dinamicmatrice);
/* carichiamo i dati nella matrice */
StampaMatrice(dinamicmatrice);
/* stampiamo la matrice, solo i caratteri però */
LiberazioneArray(dinamicmatrice);
/* liberiamo la memoria allocata per la matrice */
}
char ** AllocazioneMatrice(unsigned int * dimensioni, int typesize)
{
unsigned int matricesize = 0;
char ** dinamicmatrice;
unsigned int i = 0;
char ** iniziodati;
matricesize = dimensioni[0] * typesize + OFFSET;
/* calcoliamo il numero di elementi veri della matrice
aggiungendo i byte necessari per contenere le informazioni
sulla dimensione della matrice */
dinamicmatrice = malloc(matricesize);
/* allochiamo la memoria per contenere
la matrice e le sue dimensioni */
if(!dinamicmatrice)
return NULL;
((unsigned int *)dinamicmatrice)[0] = dimensioni[0];
/* scriviamo nei primi byte
della matrice la sua dimensione */
iniziodati = dinamicmatrice + OFFSET;
for(i = 0; i < dimensioni[0]; i++)
iniziodati[i] = AllocazioneArray(dimensioni[1], sizeof(char));
/* allochiamo lo spazio per gli array che costituiranno
le righe della matrice */
return dinamicmatrice;
}
void RiempiMatrice(char ** dinamicmatrice)
{
unsigned int dimensione = 0;
unsigned int i = 0;
char ** iniziodati;
dimensione = ((unsigned int *)dinamicmatrice)[0];
iniziodati = dinamicmatrice + OFFSET;
if(iniziodati == NULL)
return;
/* ricaviamo la dimensione della matrice
ed il puntatore all'inizio dell'array
di puntatori alle righe */
for(i = 0; i < dimensione; i++)
RiempiArray(iniziodati[i], 'A' + (i % 26));
/* carichiamo le lettere dell'alfabeto
negli array delle righe */
}
void StampaMatrice(char ** dinamicmatrice)
{
unsigned int dimensione = 0;
unsigned int i = 0;
char ** iniziodati;
dimensione = ((unsigned int *)dinamicmatrice)[0];
iniziodati = dinamicmatrice + OFFSET;
if(iniziodati == NULL)
return;
/* ricaviamo la dimensione della matrice
ed il puntatore all'inizio dell'array
di puntatori alle righe */
for(i = 0; i < dimensione; i++)
{
StampaArray(iniziodati[i]);
printf("\r\n");
}
}
void LiberazioneMatrice(char ** dinamicmatrice)
{
unsigned int dimensione = 0;
unsigned int i = 0;
char ** iniziodati;
dimensione = ((unsigned int *)dinamicmatrice)[0];
iniziodati = dinamicmatrice + OFFSET;
if(iniziodati == NULL)
return;
/* ricaviamo la dimensione della matrice
ed il puntatore all'inizio dell'array
di puntatori alle righe */
for(i = 0; i < dimensione; i++)
free(iniziodati[i]);
/* liberiamo la memoria dei singoli array */
free(dinamicmatrice);
/* infine liberiamo la memoria per l'array di puntatori */
}
E se gli array non fossero tutti della stessa dimensione?
Con minime modifiche al codice appena scritto possiamo allocare un
array che contiene come elementi degli array di differente dimensione;
comodo, no?
void main(void)
{
char ** dinamicmatrice;
int dimensioni[7] = {6, 12, 7, 3, 9, 5, 10};
dinamicmatrice = AllocazioneMatrice(dimensioni, sizeof(char *));
if(!dinamicmatrice)
return;
/* allocazione dinamica di un array di 6 elementi, ciascuna riga */
/* da n caratteri */
RiempiMatrice(dinamicmatrice);
/* carichiamo i dati nella matrice */
StampaMatrice(dinamicmatrice);
/* stampiamo la matrice, solo i caratteri per= */
LiberazioneArray(dinamicmatrice);
/* liberiamo la memoria allocata per la matrice */
}
char ** AllocazioneMatrice(unsigned int * dimensioni, int typesize)
{
unsigned int matricesize = 0;
char ** dinamicmatrice;
unsigned int i = 0;
char ** iniziodati;
matricesize = dimensioni[0] * typesize + OFFSET;
/* calcoliamo il numero di elementi veri della matrice
aggiungendo i byte necessari per contenere le informazioni
sulla dimensione della matrice */
dinamicmatrice = malloc(matricesize);
/* allochiamo la memoria per contenere
la matrice e le sue dimensioni */
if(!dinamicmatrice)
return NULL;
((unsigned int *)dinamicmatrice)[0] = dimensioni[0];
/* scriviamo nei primi byte
della matrice la sua dimensione */
iniziodati = dinamicmatrice + OFFSET;
for(i = 0; i < dimensioni[0]; i++)
iniziodati[i] = AllocazioneArray(dimensioni[1 + i], sizeof(char));
/* allochiamo lo spazio per gli array che costituiranno
le righe della matrice */
return dinamicmatrice;
}