[C] realloc disalloca le celle nel ritorno a funzione

di il
34 risposte

34 Risposte - Pagina 2

  • Re: [C] realloc disalloca le celle nel ritorno a funzione

    non mi capacito perche con reallocazioni pari, il programma non funzione.
    però a questo punto non mi è chiaro che tu abbia compreso quello che ho provato a spiegare.
    in questo punto del main:
    
        if (continua == 1)
            **linguaggio_2 = '0';
        else
        {
            crea_linguaggio_2(i,
                              copia_i,
                              continua,
                              sequenza_trovata,
                              j,
                              esito_lettura,
                              &num_sequenze_2,
                              &lunghezza_sequenza_2,
                              alfabeto,
                              sequenza,
                              linguaggio_2);
        }
       
        /* disallocazione sequenza */
        free(sequenza);
    
    all'interno della funzione crea_linguaggio_2, nel caso peggiore, la memoria puntata da linguaggio_2 viene deallocata. il chiamante da questo momento in poi si ritrova con un puntatore che punta a memoria liberata e ogni accesso è potenzialmente non valido. Il quando/come/perché accada quello che vedi non è prevedibile perché dipende da fattori all'infuori del tuo programma come eg compilatore ma soprattutto runtime di esecuzione, utilizzo della heap, solo per citare alcuni che secondo me impattano. Il fatto che accada solo con dimensioni pari è assolutamente accidentale.

    Certo, potrebbe esserci un altro bug che causa questo problema. In verità ne dubito, e in ogni caso il bug che ti ho fatto notare non può essere trascurato: sapere gestire la memoria in maniera corretta è fondamentale in C e in C++. Però non ti preoccupare, cose simili possono sempre scappare

    per risolvere, potresti modificare l'implementazione della funzione in modo che sia:
    
    char ** crea_linguaggio_2(int    i,
                           int    copia_i,
                           int    continua,
                           int    sequenza_trovata,
                           int    j,
                           int    esito_lettura,
                           int   *num_sequenze_2,
                           int   *lunghezza_sequenza_2,
                           char  *alfabeto,
                           char  *sequenza);
    
    oppure:
    
    void crea_linguaggio_2(int    i,
                           int    copia_i,
                           int    continua,
                           int    sequenza_trovata,
                           int    j,
                           int    esito_lettura,
                           int   *num_sequenze_2,
                           int   *lunghezza_sequenza_2,
                           char  *alfabeto,
                           char  ***linguaggio_2);
    
    l'obiettivo è ritornare al chiamante il puntatore ritornato dalla realloc, o come valore di ritorno o come argomento passato by reference.
  • Re: [C] realloc disalloca le celle nel ritorno a funzione

    Avevo gia provato a passare char ***linguaggio_2, ovviamente poi ho dovuto aggiungere una & nella chiamata e dei puntatori nella funzione per eliminare i warning. risultato è che il programma si arresta ancora prima ovvero quando immetto le sequenze. Sbaglio qualcosa?
  • Re: [C] realloc disalloca le celle nel ritorno a funzione

    Evidentemente sì. Se vuoi prova a copiare-incollare la nuova implementazione della funzione e la chiamata.
    Ma almeno arriva ad eseguire la chiamata a funzione?
  • Re: [C] realloc disalloca le celle nel ritorno a funzione

    void crea_linguaggio_1(int    i,
                           int    copia_i,
                           int    continua,
                           int    sequenza_trovata,
                           int    j,
                           int    esito_lettura,
                           int   *num_sequenze_1,
                           int   *lunghezza_sequenza_1,
                           char  *alfabeto,
                           char  *sequenza,
                           char ***linguaggio_1)
    {
       /* dichiarazione delle variabili locali alla funzione */
        int cont = 1;                           /* lavoro: contatore */
    
        /* inserimento e validazione sull'alfabeto delle sequenze all'interno del linguaggio */
        
        
        i = 0;
        do
        {
            for (j = 0;
                 (i < *num_sequenze_1);
                 i++)
            {
                do
                {
                    /* inserimento delle sequenze con opportune validazioni */
                    
                      inserisci_sequenze(lunghezza_sequenza_1,
                                         &cont,
                                         i,
                                         copia_i,
                                         j,
                                         esito_lettura,
                                         continua,
                                         alfabeto,
                                         sequenza);
    
                    /* validazione della sequenza di simboli all'interno dell'insieme e se valida viene memorizzata */
            
                    for (j = 0, sequenza_trovata = 1;
                         (j <= i && sequenza_trovata != 0);
                         j++)
                    {
                        sequenza_trovata = strcmp(sequenza, *linguaggio_1[j]);
                        if (sequenza_trovata == 0)
                        {
                            printf("Sequenza di simboli gia' memorizzata all'interno del linguaggio!");
                            printf(" Un insieme non puo' contenere 2 simboli uguali.\n");
                        }
                    }
                }
                while (sequenza_trovata == 0);
                if (sequenza_trovata != 0)
                {
                    strcpy(*linguaggio_1[i], sequenza);
                    cont++;
                }
            }
            /* richiesta all'utente per una modifica dell'allocazione */
    
            modifica_allocazione( esito_lettura,
                                 &continua);
    
            if (continua == 1)
            {
                /* richiesta all'utente dei dati per l'allocazione del linguaggio */
                
               *num_sequenze_1 += richiedi_righe_linguaggio(esito_lettura);
               *linguaggio_1 = (char **)realloc(linguaggio_1,
                                      *num_sequenze_1 * sizeof(char *));
                for (copia_i = 0;
                     (copia_i < *num_sequenze_1); 
                     copia_i++)
                    *linguaggio_1[copia_i] = (char *)realloc(linguaggio_1[copia_i],
                                                    *lunghezza_sequenza_1 * sizeof(char));
            }
        }
        while (continua == 1);
        printf("\nstampa primo linguaggio\n");
        for (i = 0;
             (i < *num_sequenze_1);
             i++)
            printf("%s\n",
                   *linguaggio_1[i]);
    }
    mentre nella chiamata ho messo
    (...
    ...
    &linguaggio_1)

    praticamente ho aggiunto un puntatore ad ogni evenienza di quell array....anche perchè altrimenti segnava solo warning..
    )
  • Re: [C] realloc disalloca le celle nel ritorno a funzione

    Con ad es. *linguaggio_1[1] stai accedendo a memoria non valida, causa precedenza degli operatori: viene prima eseguito linguaggio_1[1] che significa *(linguaggio_1 + 1). Però l'accesso a linguaggio_1 + 1 non è valido.
    quindi:
    1) modifica il nome del parametro della funzione da linguaggio_1 a linguaggio_1_ptr
    2) come primo statament, definisci char ** linguaggio_1 = *linguaggio_1_ptr
    3) a questo punto, elimina tutti gli * che avevi aggiunto prima, per es.
    
             sequenza_trovata = strcmp(sequenza, *linguaggio_1[j]);
    
    deve diventare
    
    	sequenza_trovata = strcmp(sequenza, linguaggio_1[j]);
    
  • Re: [C] realloc disalloca le celle nel ritorno a funzione

    Un consiglio: se è codice scritto da te, mi concentrerei sullo studio e su esercizi meno articolati, imparando mano a mano a scrivere codice più pulito.
    Perché dico questo? Un solo esempio, è sufficiente:
    
    int richiedi_righe_linguaggio(int esito_lettura); // <----- !!!!!
    
    int main(void)
    {
        char   alfabeto[SIMBOLI] = {"aeiou"},      /* input: alfabeto di simboli da tenere in considerazione */
              *sequenza,
             **linguaggio_1,                       /* input: primo linguaggio finito di simboli finiti */
             **linguaggio_2,                       /* input: secondo linguaggio finito di simboli finiti */
             **differenza,                         /* output: insieme differenza tra i due linguaggi */
             **unione;                             /* output: insieme unione tra i due linguaggi */
        int    i,                                  /* lavoro: indice degli array */
               copia_i = 0,                            /* lavoro: copia della variabile i */
               continua = 0,                       /* lavoro: condizione di proseguimento*/
               sequenza_trovata = 0,               /* lavoro: parametro per la validazione della sequenza */
               num_sequenze_1,                     /* lavoro: numero delle sequenze allocate primo linguaggio */
               lunghezza_sequenza_1 = 1,           /* lavoro: lunghezza della massima sequenza primo linguaggio */
               num_sequenze_2,                     /* lavoro: numero delle sequenze allocate secondo linguaggio */ 
               j,                                  /* lavoro: indice di scorrimento dell'array */
               lunghezza_sequenza_2,               /* lavoro: lunghezza della massima sequenza secondo linguaggio */
               max_seq,                            /* lavoro: lunghezza massima delle sequenze */
               esito_lettura = 0;                  /* lavoro: esito validazione variabili */  <----- !!!!!
               
      // .... omesso ....
    
        num_sequenze_1 = richiedi_righe_linguaggio(esito_lettura); // <----- !!!!!
    // ... omesso ....
    }
    
    nota le mie indicazioni nei commenti a margine del codice: che cosa me ne faccio della variabile del main esito_lettura che viene passata per copia in (mi pare) tutte le funzioni ? viene inizializzata a zero, e nel main sarà sempre nulla. Tanto vale usare variabili locali nelle varie funzioni, non ti pare?
  • Re: [C] realloc disalloca le celle nel ritorno a funzione

    Ha ragione, quella parte l ho mandata non modificata ma nel codice in precedenza l ho sistemata. mi dispiace pero non ho capito cosa devo modificare....dove dovrei cambiare l'identificatore dell'array nella definizione della funzione? mi perdoni..
  • Re: [C] realloc disalloca le celle nel ritorno a funzione

    elite ha scritto:


    Ha ragione, quella parte l ho mandata non modificata ma nel codice in precedenza l ho sistemata. mi dispiace pero non ho capito cosa devo modificare....dove dovrei cambiare l'identificatore dell'array nella definizione della funzione? mi perdoni..
    Devi fare una cosa del genere:
    
    void crea_linguaggio_2(int    i,
                           int    copia_i,
                           int    continua,
                           int    sequenza_trovata,
                           int    j,
                           int    esito_lettura,
                           int   *num_sequenze_2,
                           int   *lunghezza_sequenza_2,
                           char  *alfabeto,
                           char  *sequenza,
                           char ***linguaggio_2_ptr)
    {
        int cont = 1;                           /* lavoro: contatore */
        char **linguaggio_2 = *linguaggio_2_ptr;
        
        // il resto come il codice che hai postato originariamente
    }
    
    oppure, ovunque hai scritto *linguaggio_2[qualcosa] devi sostituire (*linguaggio_2)[qualcosa]. Il modo sopra, secondo me, è molto più chiaro. Però è più importante che ti sia chiaro il concetto: devi accedere alla memoria puntata da linguaggio_2, e non a quella puntata da (linguaggio_2 + qualcosa). E questa modifica serve a correggere questo comportamento.

    Mi sono concentrato sulla realloc in crea_linguaggio_2, ma noto ora che ce n'è una in crea_linguaggio_1 e in totale quattro realloc. Lascio a te il compito di verificare le altre
  • Re: [C] realloc disalloca le celle nel ritorno a funzione

    Ma avevo già provato a fare una cosa del genere, ma se passo linguaggio_2_ptr invece di linguaggio_2 nella funzione quest'ultimo non posso utilizzarlo appunto perchè non è dichiarato..
  • Re: [C] realloc disalloca le celle nel ritorno a funzione

    Guarda l'edit. quello che intendo è modificare la definizione della funzione, mica nel main dove la chiami
  • Re: [C] realloc disalloca le celle nel ritorno a funzione

    Guarda io ho sistemato ma posso dirle che non è cambiato davvero nulla rispetto a prima...non so se l ha provato
  • Re: [C] realloc disalloca le celle nel ritorno a funzione

    Non darmi del lei per favore . No non l'ho provato, però a questo punto ti direi di riflettere sulle osservazioni che ti ho fatto, verificando che il codice che ti ho proposto sia effettivamente corretto. Sono molto confidente che concettualmente il problema sia quello, ma non escluderei che ci siano altri problemi in agguato.

    Oltre a questo non vado oltre, perché significherebbe svolgere un compito o lavorare al posto tuo. Probabilmente risolverei il tuo problema, ma non ne guadagneresti molto.
    Con qualche tuo input, e domande specifiche, possiamo andare avanti: prova ad attaccare un debugger per verificare dove crasha il programma, copia/incolla un core dump ... ogni tuo contributo può essere utile per ottenere l'aiuto che ti occorre.
    Non solo da me, ma anche dalle altre persone.
  • Re: [C] realloc disalloca le celle nel ritorno a funzione

    Il problema è che questa strada l avevo gia seguita e quindi un 3o puntatore per poi far ritornare i valori. ne ho provate infinite in questi giorni ma non ne vengo a capo. risulta sempre lo stesso problema ed è ovviamente li perchè il debugger mi riporta sempre in quel punto dopo la realloc. e solo quando è maledettamente pari il valore finale dopo la realloc. non so davvero come fare penso di aver provato con tutte le strade a mia conoscenza
  • Re: [C] realloc disalloca le celle nel ritorno a funzione

    Con qualche tuo input, e domande specifiche, possiamo andare avanti: prova ad attaccare un debugger per verificare dove crasha il programma, copia/incolla un core dump ... ogni tuo contributo può essere utile per ottenere l'aiuto che ti occorre.
    Innanzitutto, la versione più aggiornata del tuo codice potrebbe essere un buon inizio ...
    Se poi descrivi in maniera precisa i passi (ie cosa passi in input al programma) che producono il crash - sarebbe già un passo in avanti.
  • Re: [C] realloc disalloca le celle nel ritorno a funzione

    
    /* programma che calcola unione e differenza tra due linguaggi finiti */
    /**********************************************************************/
    
    /*****************************/
    /* inclusione delle librerie */
    /*****************************/
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    /*****************************************/
    /* definizioni delle costanti simboliche */
    /*****************************************/
    
    #define SIMBOLI 6
    
    /********************************/
    /* dichiarazione delle funzioni */
    /********************************/
    
    void crea_linguaggio_1(int    i,
                           int    copia_i,
                           int    continua,
                           int    sequenza_trovata,
                           int    j,
                           int    esito_lettura,
                           int   *num_sequenze_1,
                           int   *lunghezza_sequenza_1,
                           char  *alfabeto,
                           char  *sequenza,
                           char  ***linguaggio_1_f);
    
    int richiedi_righe_linguaggio(int esito_lettura);
    
    int richiedi_colonne_linguaggio(int esito_lettura);
    
    void inserisci_sequenze(int  *lunghezza_sequenza_1,
                            int  *cont,
                            int   i,
                            int   copia_i,
                            int   j,
                            int   esito_lettura,
                            int   continua,
                            char *alfabeto,
                            char *sequenza);
    
    void modifica_allocazione(int  esito_lettura,
                              int *continua);
    
    void crea_linguaggio_2(int    i,
                           int    copia_i,
                           int    continua,
                           int    sequenza_trovata,
                           int    j,
                           int    esito_lettura,
                           int   *num_sequenze_2,
                           int   *lunghezza_sequenza_2,
                           char  *alfabeto,
                           char  *sequenza,
                           char ***linguaggio_2_f);
    
    void stampa_unione(int    i,
                       int    j,
                       int    num_sequenze_1,
                       int    num_sequenze_2,
                       int    sequenza_trovata,
                       char **linguaggio_1,
                       char **linguaggio_2,
                       char **unione);
    
    
    void costruisci_ric_differenza(int    i,
                                   int    j,
                                   int    sequenza_trovata,
                                   int    num_sequenze_1,
                                   int    num_sequenze_2,
                                   int    continua, 
                                   char **linguaggio_1,
                                   char **linguaggio_2,
                                   char **differenza);
    
    
    /******************************/
    /* definizione delle funzioni */
    /******************************/
    
    /* definizione della funzione main */
    int main(void)
    {
        /* dichiarazione delle variabili locali alla funzione */
        char   alfabeto[SIMBOLI] = {"aeiou"},      /* input: alfabeto di simboli da tenere in considerazione */
              *sequenza,                           /* lavoro: per validazione sequenze */ 
             **linguaggio_1,                       /* input: primo linguaggio finito di simboli finiti */
             **linguaggio_2,                       /* input: secondo linguaggio finito di simboli finiti */
             **differenza,                         /* output: insieme differenza tra i due linguaggi */
             **unione;                             /* output: insieme unione tra i due linguaggi */
        int    i,                                  /* lavoro: indice degli array */
               copia_i = 0,                        /* lavoro: copia della variabile i */
               continua = 0,                       /* lavoro: condizione di proseguimento*/
               sequenza_trovata = 0,               /* lavoro: parametro per la validazione della sequenza */
               num_sequenze_1,                     /* lavoro: numero delle sequenze allocate primo linguaggio */
               lunghezza_sequenza_1,               /* lavoro: lunghezza della massima sequenza primo linguaggio */
               num_sequenze_2,                     /* lavoro: numero delle sequenze allocate secondo linguaggio */ 
               j,                                  /* lavoro: indice di scorrimento dell'array */
               lunghezza_sequenza_2,               /* lavoro: lunghezza della massima sequenza secondo linguaggio */
               max_seq = 0,                        /* lavoro: lunghezza massima delle sequenze */
               esito_lettura = 0;                  /* lavoro: esito validazione variabili */
               
        
        /*stampa dell'alfabeto utilizzabile per la creazione dei linguaggi */
    
        printf("Utilizza l'alfabeto per la creazione di 2 linguaggi.\t{");
        for (i = 0;
             (i < SIMBOLI);
             i++)
        printf("%c ",
               alfabeto[i]);
        printf("}.\n");
    
        /* creazione da parte dell'utente del secondo linguaggio finito */
    
        printf("Crea il primo linguaggio!\n");
    
        /* richiesta all'utente dei dati per l'allocazione del linguaggio */   
    
        num_sequenze_1 = richiedi_righe_linguaggio(esito_lettura);
        if (num_sequenze_1 > 0)
            lunghezza_sequenza_1 = richiedi_colonne_linguaggio(esito_lettura);
        else 
            num_sequenze_1 = lunghezza_sequenza_1 = continua = 1;
    
    
        /* allocazione dinamica delle stringhe */
    
        linguaggio_1 = (char **)calloc(num_sequenze_1,
                                       sizeof(char*));
        for (j = 0;
             (j < num_sequenze_1); 
             j++)
            linguaggio_1[j] = (char *)calloc(lunghezza_sequenza_1, 
                                             sizeof(char));
        sequenza = (char *)calloc(lunghezza_sequenza_1,
                                  sizeof(char));
    
        /* chiamata a funzione per la creazione del primo linguaggio */
        
        if (continua == 1)
            **linguaggio_1 = '0';
        else
        {
            crea_linguaggio_1(i,
                              copia_i,
                              continua,
                              sequenza_trovata,
                              j,
                              esito_lettura,
                              &num_sequenze_1,
                              &lunghezza_sequenza_1,
                              alfabeto,
                              sequenza,
                              &linguaggio_1);
        }
        continua = 0;
        
        /* creazione da parte dell'utente del secondo linguaggio finito */
    
        printf("\nCrea il secondo linguaggio!\n");
    
        /* richiesta allocazione per il secondo linguaggio */
    
        num_sequenze_2 = richiedi_righe_linguaggio(esito_lettura);
        if (num_sequenze_2 > 0)
            lunghezza_sequenza_2 = richiedi_colonne_linguaggio(esito_lettura);
        else 
            num_sequenze_2 = lunghezza_sequenza_2 = continua = 1;
       
        /* allocazione dinamica delle stringhe */
    
        linguaggio_2 = (char **)calloc(num_sequenze_2,
                                           sizeof(char*));
        for (i = 0;
             (i < num_sequenze_2); 
             i++)
            linguaggio_2[i] = (char *)calloc(lunghezza_sequenza_2, 
                                             sizeof(char));
        /* chiamata a funzione per la creazione del secondo linguaggio */ 
        
        if (continua == 1)
            **linguaggio_2 = '0';
        else
        {
            crea_linguaggio_2(i,
                              copia_i,
                              continua,
                              sequenza_trovata,
                              j,
                              esito_lettura,
                              &num_sequenze_2,
                              &lunghezza_sequenza_2,
                              alfabeto,
                              sequenza,
                              &linguaggio_2);
        }
       
        /* disallocazione sequenza */
        free(sequenza);
        
        /* allocazione dell'insieme unione */
        
        unione = (char **)calloc(num_sequenze_1 + num_sequenze_2,
                                 sizeof(char *));
        
        if (lunghezza_sequenza_2 >= lunghezza_sequenza_1)
            max_seq = lunghezza_sequenza_2;
        else
            max_seq = lunghezza_sequenza_1;
        for (j = 0;
             (j < (num_sequenze_1 + num_sequenze_2));
             j++)
            unione[j] = (char *)calloc(max_seq + 1,
                                       sizeof(char));
    
        /* stampa dell'insieme unione dei due linguaggi */
    
        stampa_unione(i,
                      j,
                      num_sequenze_1,
                      num_sequenze_2,
                      sequenza_trovata,
                      linguaggio_1,
                      linguaggio_2,
                      unione);
    
        /* allocazione dell'insieme differenza */
    
        differenza = (char **)calloc(num_sequenze_1,
                                     sizeof(char*));
        for (j = 0;
             (j < num_sequenze_1);
             j++)
            differenza[j] = (char *)calloc(lunghezza_sequenza_1,
                                           sizeof(char));
        costruisci_ric_differenza(i = 0,
                                  j = 0,
                                  sequenza_trovata,
                                  num_sequenze_1,
                                  num_sequenze_2,
                                  continua,
                                  linguaggio_1,
                                  linguaggio_2,
                                  differenza);
    
        printf("\nL'insieme differenza tra il primo e il secondo linguaggio e':\n");
        if (*differenza[0] == '0')
            printf("vuoto!\n");
        else
        {
            for (i = 0;
                 (i < num_sequenze_1);
                 i++)
            {
                    printf("%s\n",
                           differenza[i]);
            }
        }
        /* disallocazione degli insiemi */
        
        free(linguaggio_1);
        free(linguaggio_2);
        free(unione);
        free(differenza);
        
        return(0);
    }
    
    
    /* definizione della funzione per la creazione del primo linguaggio */
    void crea_linguaggio_1(int    i,
                           int    copia_i,
                           int    continua,
                           int    sequenza_trovata,
                           int    j,
                           int    esito_lettura,
                           int   *num_sequenze_1,
                           int   *lunghezza_sequenza_1,
                           char  *alfabeto,
                           char  *sequenza,
                           char  ***linguaggio_1_f)
    {
       /* dichiarazione delle variabili locali alla funzione */
        int cont = 1;                           /* lavoro: contatore */
        char **linguaggio_1 = *linguaggio_1_f;
    
        /* inserimento e validazione sull'alfabeto delle sequenze all'interno del linguaggio */
        
        
        i = 0;
        do
        {
            for (j = 0;
                 (i < *num_sequenze_1);
                 i++)
            {
                do
                {
                    /* inserimento delle sequenze con opportune validazioni */
                    
                      inserisci_sequenze(lunghezza_sequenza_1,
                                         &cont,
                                         i,
                                         copia_i,
                                         j,
                                         esito_lettura,
                                         continua,
                                         alfabeto,
                                         sequenza);
    
                    /* validazione della sequenza di simboli all'interno dell'insieme e se valida viene memorizzata */
            
                    for (j = 0, sequenza_trovata = 1;
                         (j <= i && sequenza_trovata != 0);
                         j++)
                    {
                        sequenza_trovata = strcmp(sequenza, linguaggio_1[j]);
                        if (sequenza_trovata == 0)
                        {
                            printf("Sequenza di simboli gia' memorizzata all'interno del linguaggio!");
                            printf(" Un insieme non puo' contenere 2 simboli uguali.\n");
                        }
                    }
                }
                while (sequenza_trovata == 0);
                if (sequenza_trovata != 0)
                {
                    strcpy(linguaggio_1[i], sequenza);
                    cont++;
                }
            }
            /* richiesta all'utente per una modifica dell'allocazione */
    
            modifica_allocazione( esito_lettura,
                                 &continua);
    
            if (continua == 1)
            {
                /* richiesta all'utente dei dati per l'allocazione del linguaggio */
                
               *num_sequenze_1 += richiedi_righe_linguaggio(esito_lettura);
               linguaggio_1 = (char **)realloc(linguaggio_1,
                                      *num_sequenze_1 * sizeof(char *));
                for (copia_i = 0;
                     (copia_i < *num_sequenze_1); 
                     copia_i++)
                    linguaggio_1[copia_i] = (char *)realloc(linguaggio_1[copia_i],
                                                    *lunghezza_sequenza_1 * sizeof(char));
            }
        }
        while (continua == 1);
        printf("\nstampa primo linguaggio\n");
        for (i = 0;
             (i < *num_sequenze_1);
             i++)
            printf("%s\n",
                   linguaggio_1[i]);
    }
    
    
    /* definizione della funzione per richiedere l'allocazione del linguaggio */
    int richiedi_righe_linguaggio(int esito_lettura)
    {
        int righe;        /* output: contiene le righe di un linguaggio */       
    
        /* richiesta all'utente delle dimensioni dei linguaggi */
        do
        {
            printf("Quante sequenze finite di simboli, presi dall'alfabeto, ");
            printf("vuoi aggiungere all'interno del linguaggio? (>= 0)  ");
            esito_lettura = scanf("%d",
                                  &righe);
            if (esito_lettura != 1 || righe < 0)
                printf("Valore non accettabile!\n");
            while (getchar() != '\n');
        }
        while (esito_lettura != 1 || righe < 0);
        return(righe);
    }
    
    
    int richiedi_colonne_linguaggio(int esito_lettura)
    {
        int colonne;      /* output: contiene le colonne del linguaggio */  
        do
        {
            printf("Quale sara' la lunghezza massima della sequenza (>0)  ");
            esito_lettura = scanf("%d",
                                  &colonne);
            if (esito_lettura != 1 || colonne <= 0)
                printf("Valore non accettabile!\n");
            while (getchar() != '\n');
        }
        while (esito_lettura != 1 || colonne <= 0);
        return(colonne);
    }
    /* definizione della funzione per inserire nuove sequenze con opportune validazioni */
    void inserisci_sequenze(int  *lunghezza_sequenza_1,
                            int  *cont,
                            int   i,
                            int   copia_i,
                            int   j,
                            int   esito_lettura,
                            int   continua,
                            char *alfabeto,
                            char *sequenza)
    {
        /* inserimento e validazione delle sequenze */
        do
        {
            printf("\nInserisci la sequenza %d rispettando la lunghezza scelta:   ",
                   *cont);
            scanf("%s",
                  sequenza);
            esito_lettura = strlen(sequenza);
            for (j = 0, continua = 1;
                 (continua == 1 && esito_lettura <= (int)*lunghezza_sequenza_1 && sequenza[j] != '\0');
                 j++)
            {
                for (copia_i = continua = 0; 
                        (copia_i <= SIMBOLI && continua == 0);
                     copia_i++)
                {
                    if (sequenza[j] == alfabeto[copia_i])
                        continua = 1;
                    else
                        continua = 0;
                }
            }
            if (continua == 0)
                printf("Sequenza di simboli non valida!\n");
        }
        while (continua == 0 || esito_lettura > (int)*lunghezza_sequenza_1); 
    }
               
    /* definizione della funzione per eventuale modifica dell'allocazione*/
    void modifica_allocazione(int  esito_lettura,
                              int *continua)
    {
        do
        {
            printf("Vuoi memorizzare altre sequenze di simboli all'interno del linguaggio? (1 = si, 0 = no)  ");
            esito_lettura = scanf("%d",
                                  continua);
            if (esito_lettura != 1 || *continua < 0 || *continua > 1)
                printf("Valore non accettabile!");
            while (getchar() != '\n');
        }
        while (esito_lettura != 1 || *continua < 0 || *continua > 1);
    }
    
    void crea_linguaggio_2(int    i,
                           int    copia_i,
                           int    continua,
                           int    sequenza_trovata,
                           int    j,
                           int    esito_lettura,
                           int   *num_sequenze_2,
                           int   *lunghezza_sequenza_2,
                           char  *alfabeto,
                           char  *sequenza,
                           char ***linguaggio_2_f)
    {
        int cont = 1;                           /* lavoro: contatore */
        char **linguaggio_2 = *linguaggio_2_f;
    
         
    
        /* inserimento e validazione sull'alfabeto delle sequenze all'interno del linguaggio */
        
        if (*num_sequenze_2 > 0)
            printf("Inserisci le sequenze di simboli nel secondo linguaggio.\n");
        sequenza = (char *)calloc(*lunghezza_sequenza_2,
                                  sizeof(char));
        i = 0;
        do
        {
            for (j = 0;
                 (i < *num_sequenze_2);
                 i++)
            {
                do
                {
                    /* inserimento delle sequenze con opportune validazioni */
                    
                      inserisci_sequenze(lunghezza_sequenza_2,
                                         &cont,
                                         i,
                                         copia_i,
                                         j,
                                         esito_lettura,
                                         continua,
                                         alfabeto,
                                         sequenza); 
                
                    /* validazione della sequenza di simboli all'interno dell'insieme e se valida viene memorizzata */
            
                    for (j = 0, sequenza_trovata = 1;
                         (j <= i && sequenza_trovata != 0);
                         j++)
                    {
                        sequenza_trovata = strcmp(sequenza, linguaggio_2[j]);
                        if (sequenza_trovata == 0)
                        {
                            printf("Sequenza di simboli gia' memorizzata all'interno del linguaggio!");
                            printf(" Un insieme non puo' contenere 2 simboli uguali.\n");
                        }
                    }
                }
                while (sequenza_trovata == 0);
                if (sequenza_trovata != 0)
                {
                    strcpy(linguaggio_2[i], sequenza);
                    cont++;
                }
            }
            /* richiesta all'utente per una modifica dell'allocazione */
    
            modifica_allocazione( esito_lettura,
                                 &continua);
    
            if (continua == 1)
            {
                /* richiesta all'utente dei dati per l'allocazione del linguaggio */
                
                *num_sequenze_2 += richiedi_righe_linguaggio(esito_lettura);
                linguaggio_2 = realloc(linguaggio_2,
                                       *num_sequenze_2 * sizeof(char *));
                for (copia_i = 0;
                     (copia_i < *num_sequenze_2); 
                     copia_i++)
                    linguaggio_2[copia_i] = realloc(linguaggio_2[copia_i],
                                                    *lunghezza_sequenza_2 * sizeof(char));
            }
        }
        while (continua == 1);
        printf("\nstampa secondo linguaggio\n");
        for (i = 0;
             (i < *num_sequenze_2);
             i++)
            printf("%s\n",
                   linguaggio_2[i]);
    }
    
    /* definizione della funzione che stampa l'unione dei due linguaggi */
    void stampa_unione(int    i,
                       int    j,
                       int    num_sequenze_1,
                       int    num_sequenze_2,
                       int    sequenza_trovata,
                       char **linguaggio_1,
                       char **linguaggio_2,
                       char **unione)
    {
        /* costruzione e stampa dell'insieme unione tra i due linguaggi */
    
        int z = num_sequenze_1;       /* lavoro: indice della matrice unione */
        for (j = 0;
             (j < num_sequenze_1);
             j++)
            strcpy(unione[j], linguaggio_1[j]);
        for (i = 0;
             (i < num_sequenze_2);
             i++)
        {
            for (j = 0, sequenza_trovata = 1;
                 (j < num_sequenze_1 && sequenza_trovata != 0);
                 j++)
                sequenza_trovata = strcmp(linguaggio_2[i], linguaggio_1[j]);
            {
                while (sequenza_trovata != 0)
                {
                    strcpy(unione[z], linguaggio_2[i]);
                    sequenza_trovata = 0;
                    z++;
                }
            }
        }
        printf("\nL'insieme unione tra i due linguaggi e':\n");
        if (*unione[0] == '0')
            printf("vuoto!\n");
        else 
        {
            for (i = 0;
                 (i < (num_sequenze_1 + num_sequenze_2));
                 i++)
            {
                printf("%s\n",
                       unione[i]);
            }
        }
    }
    
    /* definizione della funzione che stampa la differenza tra il primo e secondo linguaggio */
    void costruisci_ric_differenza(int    i,
                                   int    j,
                                   int    sequenza_trovata,
                                   int    num_sequenze_1,
                                   int    num_sequenze_2,
                                   int    continua,
                                   char **linguaggio_1,
                                   char **linguaggio_2,
                                   char **differenza)
    {
        int z;                     /*lavoro: indice matrice di supporto */
    
        /* costruzione ricorsiva dell'insieme differenza tra il primo e il secondo linguaggio */
        /* caso base */
    
        if (*linguaggio_2[num_sequenze_2 - 1] == '0')
        {
            for (j = continua = 0;
                 (j < num_sequenze_1 && continua == 0);
                 j++)
            {
                if (*linguaggio_1[j] != '0')
                    continua = 1;
            }
            if (continua == 1)
            {
                for (i = j = 0;
                     (i < num_sequenze_1);
                     i++)
                    if (*linguaggio_1[i] != '0')
                    {
                        strcpy(differenza[j], linguaggio_1[i]);
                        j++;
                    }
            }
            else 
                *differenza[0] = '0';
        }
        else
        /* caso generale */
        {
                
            for (z = 0, sequenza_trovata = 1;
                 (z < num_sequenze_2 && sequenza_trovata != 0);
                 z++)
            sequenza_trovata = strcmp(linguaggio_1[i], linguaggio_2[z]);
            z = 0;
            if (sequenza_trovata == 0)
                *linguaggio_1[i] = '0';
            *linguaggio_2[j] = '0';
    
            costruisci_ric_differenza(i + 1,
                                      j + 1,
                                      sequenza_trovata,
                                      num_sequenze_1,
                                      num_sequenze_2,
                                      continua,
                                      linguaggio_1,
                                      linguaggio_2,
                                      differenza);
        } 
    }

    questa è la versione più aggiornata con le ultime modifiche e spero siano fatte bene almeno quelle a sto punto..
    dopo aver allocato inizialmente a 4 a tempo di esecuzione e poi deciso di aumentarne la memoria di 1 (la somma attualmente è 5 quindi dispari) il debugger nella funzione crea_linguaggio_1 riporta nelle varie sezioni ad esempio
    
    linguaggio_1[0] = aa
    linguaggio_1[1] = ee
    linguaggio_1[2] = ii
    linguaggio_1[3] = oo
    ..
    tornato nel main questo linguaggio resta invariato mentre con un 3+1 quindi pari nella funzione rimane come appena creato ovviamente e tornato nel main invece
    
    linguaggio_1[0] = 0x6f6f
    linguaggio_1[1] = 0x0
    linguaggio_1[2] = ii (qui rimane invariato)
    linguaggio_1[3] = 0x0
Devi accedere o registrarti per scrivere nel forum
34 risposte