Questo è un classico assoluto in ambito didattico. Questa versione contiene anche tutto il codice per la programmazione difensiva e le relative #define per la simulazione dei faults, che per il momento possono essere tranquillamente ignorate privilegiando la comprensione della logica di base, ma vanno comunque tesaurizzate per il futuro.
/************************************************************************/
/** Scopo del programma: **/
/** Allocazione didattica di array nested (multidimensionali) **/
/************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define ASIZE (8)
typedef enum {FALSE, TRUE} Bool_t;
#ifdef ALLOC_FAIL_02
#ifdef ALLOC_FAIL_01
#undef ALLOC_FAIL_01
#endif
#pragma message (">> TEST VERSION compiled with ALLOC_FAIL_02 defined")
#endif
#ifdef ALLOC_FAIL_01
#pragma message (">> TEST VERSION compiled with ALLOC_FAIL_01 defined")
#endif
Bool_t matrix_alloc(int ***m, const unsigned int row, const unsigned int col)
{
unsigned int i;
assert(row > 0);
assert(col > 0);
/*
** PRIMO STEP: allocazione array di base
*/
#ifdef ALLOC_FAIL_01
*m = NULL;
#else
*m = (int **)malloc(row * sizeof(int *));
#endif
if (NULL == *m)
{
fputs("Errore di allocazione base array !\n", stderr);
return (FALSE);
}
for (i = 0; i < row; ++i)
{
int *p;
/*
** SECONDO STEP: allocazione di ogni singolo array-riga
*/
p = (int *)malloc(col *sizeof(int));
#ifdef ALLOC_FAIL_02
if (row -1 == i)
{
free(p);
p = NULL;
}
#endif
if (NULL != p)
{
/*
** TERZO e ULTIMO STEP: collegamento riga ad array base
*/
(*m)[i] = p;
}
else
{
fprintf(stderr, "Errore di allocazione alla riga %d!\n"
"Deallocazione array: ", i);
while (i--)
{
free((*m)[i]);
fprintf(stderr, "%d ", i);
}
free(*m);
return (FALSE);
}
}
return (TRUE);
}
int main(void)
{
int **array, righe, colonne;
int i, j;
Bool_t status;
righe = ASIZE;
colonne = ASIZE;
printf("Allocazione dinamica di un array "
"bidimensionale %d x %d\n",
righe, colonne);
status = matrix_alloc(&array, righe, colonne);
if(status)
{
printf("** Allocazione effettuata. "
"Inizializzazione di %d celle in corso...\n",
righe * colonne);
for (i = 0; i < righe; ++i)
{
for (j = 0; j < colonne; ++j)
{
array[ i ][ j ] = i * 10 + j;
}
}
puts("** Contenuto dell'array:");
for (i = 0; i < righe; ++i)
{
for (j = 0; j < colonne; ++j)
{
printf( "array[%d][%d] = %02d\n", i, j, array[ i ][ j ]);
}
puts("");
free(array[i]);
}
free(array);
}
return (EXIT_SUCCESS);
}/* EOF: alloc_array.c */
PS: quando presenti codice sorgente, devi usare gli appositi tag Code.