codice:
/*
** alloc_example.c
**
** Esempi di allocazione con passaggio di puntatori a vari livelli
** di indirezione.
**
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#define DIM (6)
/********************************************************************/
#ifdef ALLOC_FAIL_01
#pragma message("Compilazione di TEST con ALLOC_FAIL_01 abilitato.")
#endif
#ifdef ALLOC_FAIL_02
#pragma message("Compilazione di TEST con ALLOC_FAIL_02 abilitato.")
#endif
#ifdef ALLOC_FAIL_03
#pragma message("Compilazione di TEST con ALLOC_FAIL_03 abilitato.")
#ifdef TEST_AT
#undef TEST_AT
#endif
#define TEST_AT (r-3)
#endif
#ifdef ALLOC_FAIL_04
#pragma message("Compilazione di TEST con ALLOC_FAIL_04 abilitato.")
#endif
#ifdef ALLOC_FAIL_05
#pragma message("Compilazione di TEST con ALLOC_FAIL_05 abilitato.")
#ifdef TEST_AT
#undef TEST_AT
#endif
#define TEST_AT (2)
#endif
#ifdef ALLOC_FAIL_06
#pragma message("Compilazione di TEST con ALLOC_FAIL_06 abilitato.")
#endif
#ifdef ALLOC_FAIL_07
#pragma message("Compilazione di TEST con ALLOC_FAIL_07 abilitato.")
#endif
#ifdef ALLOC_FAIL_08
#pragma message("Compilazione di TEST con ALLOC_FAIL_08 abilitato.")
#ifdef TEST_AT
#undef TEST_AT
#endif
#define TEST_AT (r-1)
#endif
#ifdef ALLOC_FAIL_09
#pragma message("Compilazione di TEST con ALLOC_FAIL_09 abilitato.")
#ifdef TEST_AT
#undef TEST_AT
#endif
#define TEST_AT (c-3)
#endif
/********************************************************************/
typedef enum {FALSE, TRUE} boole_t;
typedef struct
{
char *myString;
size_t myStrLen;
int iVal;
} myStruct_t;
boole_t alloc_vector(int **v, const size_t s);
boole_t alloc_string(char **st, size_t *s);
boole_t alloc_string_vect(char ***m, const size_t r, size_t *c);
boole_t alloc_string_matrix(char ****m, const size_t r, const size_t c, size_t *le);
boole_t alloc_struct_vect(myStruct_t **ms, const size_t s, size_t *le);
boole_t alloc_struct_matrix(myStruct_t ***ms, const size_t r, const size_t c, size_t *le);
/********************************************************************/
/********************************************************************/
int main(void)
{
boole_t status = FALSE;
size_t i;
char ***ma = NULL;
char **m = NULL;
char *s = NULL;
myStruct_t *ms = NULL;
int *v = NULL;
size_t vDim = 0;
puts("Esempi di allocazione indiretta con passaggio di\n"
"puntatori a vari livelli di indirezione.\n");
puts("1) Allocazione stringa singola.");
status = alloc_string(&s, &vDim);
if(status)
{
printf(" Dimensione....: %d\n"
" Contenuto.....: [%s]\n", vDim, s);
free(s);
}
else
{
puts(">>> Errore di allocazione!");
}
puts("\n2) Allocazione vettore di stringhe.");
status = alloc_string_vect(&m, DIM, &vDim);
if(status)
{
printf(" Dimensione....: %d\n"
" Contenuti.....:\n", vDim);
for(i = 0; i < DIM; ++i)
{
printf(" m[%d]: \"%s\"\n", i, m[i]);
free(m[i]);
}
free(m);
}
else
{
puts(">>> Errore di allocazione!");
}
puts("\n3) Allocazione vettore di strutture.");
status = alloc_struct_vect(&ms, DIM, &vDim);
if (status)
{
puts(" Contenuti.....:");
for(i = 0; i < DIM; ++i)
{
printf(" ms[%d].myString.....: \"%s\"\n"
" ms[%d].myStrLen.....: %d\n"
" ms[%d].iVal.........: %d\n",
i, ms[i].myString,
i, ms[i].myStrLen,
i, ms[i].iVal);
free(ms[i].myString);
}
free(ms);
}
else
{
puts(">>> Errore di allocazione!");
}
puts("\n4) Allocazione vettore di interi.");
status = alloc_vector(&v, DIM);
if (status)
{
puts(" Contenuti.....:");
for(i = 0; i < DIM; ++i)
{
printf(" v[%d] = %d\n", i, v[i]);
}
free(v);
}
else
{
puts(">>> Errore di allocazione!");
}
puts("\n5) Allocazione matrice di stringhe.");
status = alloc_string_matrix(&ma, DIM, DIM, &vDim);
if (status)
{
puts(" Contenuti.....:");
for(i = 0; i < DIM; ++i)
{
size_t j;
for (j = 0; j < DIM; ++j)
{
printf(" ma[%d][%d] = \"%s\"\n", i, j, ma[i][j]);
free(ma[i][j]);
}
puts("");
free(ma[i]);
}
free(ma);
}
else
{
puts(">>> Errore di allocazione!");
}
return status ? EXIT_SUCCESS : EXIT_FAILURE;
}
/********************************************************************/
/********************************************************************/
boole_t alloc_string(char **st, size_t *s)
{
const char *string = "Stringa di prova.";
assert(NULL != s);
*s = strlen(string) + 1;
#ifdef ALLOC_FAIL_01
*st = NULL;
fprintf(stderr, "- simulazione errore di allocazione stringa.\n");
#else
*st = (char *)malloc((*s) * sizeof(char));
#endif
if (NULL != *st)
{
strcpy(*st, string);
}
return (boole_t)(NULL != *st);
}
/********************************************************************/
boole_t alloc_string_vect(char ***m, const size_t r, size_t *c)
{
const char *string = "Stringa_";
boole_t retval = FALSE;
assert(NULL != c);
assert(r > 1);
*c = strlen(string) + 3;
#ifdef ALLOC_FAIL_02
*m = NULL;
fprintf(stderr, "- simulazione errore di allocazione vettore.\n");
#else
*m = (char **)malloc(r * sizeof(char *));
#endif
if (NULL != *m)
{
size_t i;
retval = TRUE;
for(i = 0; i < r; ++i)
{
char *p;
p = (char *)malloc(*c * sizeof(char));
#ifdef ALLOC_FAIL_03
if (TEST_AT == i)
{
free(p);
p = NULL;
fprintf(stderr, "- simulazione errore di allocazione elemento %d\n", i);
}
#endif
if (NULL != p)
{
sprintf(p, "%s%02d", string, i +1);
(*m)[i] = p;
}
else
{
do
{
--i;
free((*m)[i]);
fprintf(stderr, "- deallocazione elemento %d\n", i);
} while(i);
free(*m);
retval = FALSE;
break;
}
}
}
return retval;
}
/********************************************************************/
boole_t alloc_struct_vect(myStruct_t **ms, const size_t r, size_t *le)
{
const char *string = "Stringa-in-struct_";
boole_t retval = FALSE;
assert(NULL != le);
assert(r > 1);
*le = strlen(string) +3;
#ifdef ALLOC_FAIL_04
*ms = NULL;
fprintf(stderr, "- simulazione errore di allocazione vettore.\n");
#else
*ms = (myStruct_t *)malloc(r * sizeof(myStruct_t));
#endif
if (NULL != *ms)
{
size_t i;
retval = TRUE;
for(i = 0; i < r; ++i)
{
char *p;
p = (char *)malloc((*le) * sizeof(char));
#ifdef ALLOC_FAIL_05
if (TEST_AT == i)
{
free(p);
p = NULL;
fprintf(stderr, "- simulazione errore di allocazione elemento %d\n", i);
}
#endif
if(NULL != p)
{
sprintf(p, "%s%02d", string, i);
((*ms)[i]).myString = p;
((*ms)[i]).myStrLen = strlen(p);
((*ms)[i]).iVal = i;
}
else
{
while (i--)
{
free((*ms)[i].myString);
fprintf(stderr, "- deallocazione elemento %d\n", i);
}
free(*ms);
retval = FALSE;
break;
}
}
}
return retval;
}
/********************************************************************/
boole_t alloc_vector(int **v, const size_t s)
{
boole_t retval = FALSE;
size_t i;
assert(s > 1);
#ifdef ALLOC_FAIL_06
*v = NULL;
fprintf(stderr, "- simulazione errore di allocazione vettore.\n");
#else
*v = (int *)malloc(s * sizeof(int));
#endif
if (NULL != *v)
{
for(i = 0; i < s; ++i)
{
(*v)[i] = i;
}
retval = TRUE;
}
return retval;
}
/********************************************************************/
boole_t alloc_string_matrix(char ****m, const size_t r,
const size_t c, size_t *le)
{
const char *string = "Testo_";
boole_t retval = FALSE;
assert(NULL != le);
assert(r > 1);
assert(c > 1);
*le = strlen(string) + 6;
#ifdef ALLOC_FAIL_07
*m = NULL;
fprintf(stderr, "- simulazione errore di allocazione matrice.\n");
#else
*m = (char ***)malloc(r * sizeof(char **));
#endif
if (NULL != *m)
{
size_t i, j;
retval = TRUE;
for(i = 0; i < r; ++i)
{
char **p;
p = (char **)malloc(c * sizeof(char *));
#ifdef ALLOC_FAIL_08
if (TEST_AT == i)
{
free(p);
p = NULL;
fprintf(stderr, "- simulazione errore di allocazione riga %d\n", i);
}
#endif
if (NULL != p)
{
(*m)[i] = p;
for (j = 0; j < c; ++j)
{
char *q;
q = (char *)malloc((*le) * sizeof(char));
#ifdef ALLOC_FAIL_09
if ((TEST_AT == j) && (TEST_AT == i))
{
free(q);
q = NULL;
fprintf(stderr, "- simulazione errore di allocazione"
" elemento %d, riga %d\n", j, i);
}
#endif
if (NULL != q)
{
sprintf(q, "%s%02d_%02d", string, i +1, j +1);
(*m)[i][j] = q;
}
else
{
while (j--)
{
free((*m)[i][j]);
fprintf(stderr, "- deallocazione elemento %d\n", j);
}
free((*m)[i]);
retval = FALSE;
break;
}
}
}
else
{
retval = FALSE;
}
if (!retval)
{
size_t k;
for (k = 0; k < i; ++k)
{
fprintf(stderr, "- riga %d:\n", k);
if (NULL != (*m)[k][0])
{
for (j = 0; j < c; ++j)
{
free((*m)[k][j]);
fprintf(stderr, " - deallocazione elemento %d\n", j);
}
}
free((*m)[k]);
fprintf(stderr, " - deallocazione riga %d\n", k);
}
free(*m);
break;
}
}
}
return retval;
}
/********************************************************************/
boole_t alloc_struct_matrix(myStruct_t ***ms, const size_t r,
const size_t c, size_t *le)
{
return TRUE;
}
/********************************************************************/
/* EOF: alloc_example.c */
/********************************************************************/