Visualizzazione dei risultati da 1 a 9 su 9

Discussione: Char x char... S x s

Visualizzazione discussione

  1. #8
    Quote Originariamente inviata da caramelleamare Visualizza il messaggio
    Quando quello che dovrò programmare avrà un senso mi ricorderò delle tre regole fondamentali da te esposte, sperando di ricordarle tutte perché sono davvero molto articolate.
    Come già ebbe a dire un giovane e burlone fisico statistico su un altro forum, quelle regole puoi sempre fartele tatuare su un avambraccio, così da risparmiare sinapsi, usandole invece per memorizzare i contenuti di questi testi, dei quali tali regole sono un minimale frammento.

    Riguardo ai puntatori, potrebbe anche interessarti studiare questo sempreverde esempio, che illustra una silloge di tecniche di buona programmazione ed engineering coerente, MISRA/C compatibile, pur mantenendo uno stile ampiamente accettabile didatticamente.
    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                                             */
    /********************************************************************/


    E' inoltre caldamente consigliato l'uso di Valgrind, o equivalentemente di DrMemory, quando si giocherella con puntatori assortiti e allocazione dinamica.
    Ultima modifica di M.A.W. 1968; 30-11-2014 a 15:41 Motivo: mistype
    • Un plauso a Grisha Perelman, raro esempio di genuino anticonformismo umano e scientifico.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.