Consiglio Manuali-ListaDoppiamentePuntata tipo dato generico

di il
75 risposte

75 Risposte - Pagina 5

  • Re: Consiglio Manuali-ListaDoppiamentePuntata tipo dato generico

    Quel problema te lo da un banale ;
    
    typedef struct abrgenerico{
        void * info;
        struct abrgenerico *sx;
        struct abrgenerico *dx   // Qui manca il ;
    } abr;
    
  • Re: Consiglio Manuali-ListaDoppiamentePuntata tipo dato generico

    Uh e chi se ne era accorto!
    Ora compila! Si blocca in esecuzione nella funzione compare
  • Re: Consiglio Manuali-ListaDoppiamentePuntata tipo dato generico

    Non si blocca sulla compare ma sull'inserimento del dato.

    Allora ti posto il codice così puoi controllarlo e cercare di comprendere gli errori concettuali.

    L'errore del ; lo correggi con una migliore scrittura del codice, meglio aggiungere uno spazio bianco in più, una riga bianca in più, una parentesi in più. Ciò rende il codice più leggibile e manutenibile.
    E' un buon esercizio leggere il codice scritto da altri, puoi farlo anche qui sul forum, ti renderai conto di quanto più difficile sia trovare gli errori, a maggior ragione se il codice non è scritto in maniera leggibile.

    main.c
    
    #include <stdio.h>
    #include <stdlib.h>
    #include "abrgenerico.h"
    #include "dati.h"
    
    
    int main() {
        int n;
        ABR albero=NULL;
        int i;
        int sceltatipo;
    
        int *dato;
    
        printf("COSTRUISCI ABR:\n");
        printf("1) Interi.\n");
        printf("2) Stringhe\n");
        printf("Scegli il tipo dei dato:> ");
        scanf("%d",&sceltatipo);
        printf("Quanti elementi vuoi inserire?");
        scanf("%d",&n);
    
        switch (sceltatipo) {
        case 1:
            for (i=0; i<n; i++) {
                //dato = getInputINT();
                dato = getRandomInt();
                albero=abr_insert(albero,(void *)dato, compareINT);
            }
            abr_printing(albero, printINT);
        }
    
        return 0;
    }
    
    dati.h
    
    #ifndef DATI_H_INCLUDED
    #define DATI_H_INCLUDED
    
    #include "datoINT.h"
    //#include "datoSTRING.h"
    
    #endif // DATI_H_INCLUDED
    
    abrgenerico.h
    
    #ifndef ABRGENERICO_H_INCLUDED
    #define ABRGENERICO_H_INCLUDED
    
    typedef struct abrgenerico * ABR;
    
    typedef int (*COMPARE)(void * , void * );
    typedef void (*PRINT)(void *);
    
    ABR abr_insert(ABR , void * , COMPARE );
    void abr_printing(ABR , PRINT );
    
    
    #endif // ABRGENERICO_H_INCLUDED
    
    abrgenerico.c
    
    #include <stdio.h>
    #include <stdlib.h>
    #include "abrgenerico.h"
    
    
    typedef struct abrgenerico {
        void * info;
        ABR sx;
        ABR dx;
    } abr;
    
    
    ABR abr_insert(ABR t, void *item, COMPARE confronta) {
        int pos;
        ABR tmp;
    
        if (t!=NULL) {
            pos = confronta(t->info, item);
            if ( pos > 0)
                t->sx = abr_insert(t->sx, item, confronta);
            else if ( pos < 0 )
                t->dx = abr_insert(t->dx, item, confronta);
            return t;
        }
        else {
            tmp=(abr *)malloc(sizeof(abr));
            if(tmp == NULL) {
                printf("Error: allocation abr node failed!\n");
                exit(-1);
            }
            tmp->info=item;
            tmp->sx=NULL;
            tmp->dx=NULL;
            return tmp;
        }
    }
    
    void abr_printing(ABR t, PRINT printing) {
        if(t==NULL)
            return;
    
        abr_printing(t->sx, printing);
        printing(t->info);
        abr_printing(t->dx, printing);
    
        return;
    }
    
    datoINT.h
    
    #ifndef DATOINT_H_INCLUDED
    #define DATOINT_H_INCLUDED
    
    int compareINT(void * , void * );
    int * getInputINT(void );
    int * getRandomINT(void );
    void printINT(void *);
    
    #endif // DATOINT_H_INCLUDED
    
    datoINT.c
    
    #include <stdio.h>
    #include <stdlib.h>
    #include "datoINT.h"
    
    int compareINT(void *a, void *b) {
        int A, B;
        A = *((int *)a);
        B = *((int *)b);
        return A-B;
    }
    
    int * getInputINT(void){
        int *in;
        in = (int *)malloc(sizeof(int));
        if(in == NULL){
            printf("Error: allocation int failed\n");
            exit(-1);
        }
        printf("Inserisci un valore intero:");
        scanf("%d", in);
        return in;
    }
    
    int * getRandomINT(void) {
        int *d;
        d = (int *)malloc(sizeof(int));
        if(d == NULL){
            printf("Error: allocation int failed\n");
            exit(-1);
        }
        *d = (rand()%100) ;
        return d;
    }
    
    
    void printINT(void *dato){
        printf("%d\n", *(int *)dato);
    }
    
    
  • Re: Consiglio Manuali-ListaDoppiamentePuntata tipo dato generico

    Ok funziona! Il problema era in getInputINT avevo saltato distrattamente l'allocazione! Grazie mille!
  • Re: Consiglio Manuali-ListaDoppiamentePuntata tipo dato generico

    Certo che funziona. Ma attento che devi ancora scrivere le funzioni di cancellazione di un dato, ricerca, distruzione dell'albero.
  • Re: Consiglio Manuali-ListaDoppiamentePuntata tipo dato generico

    Mentre sto scrivendo le funzioni, mi è venuta un'idea.. se creassi un altra struttura di questo tipo?
    typedef struct abrgenerico * ABRG;
    typedef struct abr_t * ABR;
    typedef struct abrgenerico
    {
        void * info;
        struct abrgenerico * sx;
        struct abrgenerico * dx;
    } abrgenerico;
    
    typedef struct
    {
        ABRG abr;
        int (*COMPARE)(void * , void * );
        void (*STAMPA) (void *);
    }abr_t;
    
    in modo che dal main una volta scelto il tipo, associo ai campi dell'abr da allocare, le funzioni specifiche di quel tipo di dato.. e poi le funzioni di inserimento e cancellazione ecc vengono chiamate con l'argomento mancante compare o stampa...
    Ho pensato questo perchè mi è sembrato che poi dal main può essere più facile gestire la manipolazione dell'abr se il nodo contiene già la informazioni riguardo il tipo di funzioni da richiamare..
  • Re: Consiglio Manuali-ListaDoppiamentePuntata tipo dato generico

    Non ho mai fatto qualcosa di simile, puoi provare; anche se non ho capito quali potessero essere i vantaggi di ciò.
  • Re: Consiglio Manuali-ListaDoppiamentePuntata tipo dato generico

    Mi è venuta questa idea perchè ho pensato alla scrittura di un main di esempio per utilizzare la libreria generica.. E ho pensato che se scrivo un programma in cui offro la possibilità all'utente di inserire un abr di qualsiasi tipo, e poi successivamente di effettuare ogni tipo di operazione su di esso, che possa essere la stampa piuttosto che la cancellazione, o altre.. Fin quando si tratta dell'inserimento, l'utente sceglie il tipo di dato, e dal programma scrivo appunto il codice che per ogni tipo di dato effettua l'inserimento adeguato chiamando la funzione inserimento con la giusta funzione di confronto.. Invece nel caso in cui voglio far visualizzare il contenuto dell'abr, nel codice diventa difficile scrivere quale funzione di stampa deve chiamare, in quanto la scelta la faccio effettuare all'utente soltanto del caso dell'inserimento. Se scrivessi invece una struttura dati che già contiene le informazioni di confronto e stampa, nel momento dell'inserimento allocherei anche queste informazioni, per cui successivamente quando voglio effettuare la visualizzazione del contenuto, in base a tali informazioni il programma già sa quale funzione della libreria dati utilizzare.
    Non so se sono stato molto chiaro...

    P.S : Diciamo che è un'idea, e una curiosità in più perchè in realtà ciò esula da quello che io devo fare, in quando io devo scrivere la libreria generica.. la programmazione del main non mi "interessa". Tanto è vero che poi devo estendere la libreria generica a quella precedentemente creata (su abr di tipo strighe) , quindi anche quel caso ho un main abbastanza specifico.
  • Re: Consiglio Manuali-ListaDoppiamentePuntata tipo dato generico

    Ecco le funzioni che ho fin ora scritto.. Per il momento con il main scritto così funziona tutto tranne l'inserimento manuale di char...
    abrgenerico.h
    #ifndef ABRGENERICO_H_INCLUDED
    #define ABRGENERICO_H_INCLUDED
    
    typedef struct abrgenerico * ABR;
    typedef int (*COMPARE)(void * , void * );
    typedef void (*STAMPA) (void *);
    
    ABR abr_insert(ABR t, void* item, COMPARE compare);
    void abr_stampaInOrder (ABR t, STAMPA stamp);
    void abr_stampaPreOrder (ABR t, STAMPA stamp);
    void abr_stampaPostOrder (ABR t, STAMPA stamp);
    ABR abr_cancel(ABR t, void *elem, COMPARE compare);
    ABR abr_staccamin(ABR p, ABR t);
    ABR abr_cancellanodo(ABR t);
    ABR abr_svuota (ABR t);
    
    #endif // ABRGENERICO_H_INCLUDED
    
    abrgenerico.c
    #include <stdio.h>
    #include <stdlib.h>
    #include "abrgenerico.h"
    
    typedef struct abrgenerico
    {
        void * info;
        struct abrgenerico * sx;
        struct abrgenerico * dx;
    } abr;
    
    
    ABR abr_insert(ABR t, void* item, COMPARE compare)
    {
        int pos;
        if (t!=NULL)
        {
            pos=compare(item,t->info);
            if ( pos < 0)
                t->sx=abr_insert(t->sx,item,compare);
            else if ( pos > 0 )
                t->dx=abr_insert(t->dx,item,compare);
    
            return t;
            }
    
        else
        {
            ABR tmp=(abr *)malloc(sizeof(abr));
            if(tmp == NULL) {
                printf("Error: allocation abr node failed!\n");
                exit(-1);
            }
            tmp->info=item;
            tmp->sx=NULL;
            tmp->dx=NULL;
            return tmp;
            }
    }
    
    void abr_stampaInOrder (ABR t, STAMPA stamp)
    {
        if (t==NULL) return;
    
        if (t->sx!=NULL) abr_stampaInOrder(t->sx,stamp);
        stamp(t->info);
        if(t->dx!=NULL) abr_stampaInOrder(t->dx,stamp);
    
        return;
    
    }
    
    void abr_stampaPreOrder (ABR t, STAMPA stamp)
    {
        if (t==NULL) return;
    
        stamp(t->info);
        if (t->sx!=NULL) abr_stampaPreOrder(t->sx,stamp);
        if(t->dx!=NULL) abr_stampaPreOrder(t->dx,stamp);
    
        return;
    
    }
    
    void abr_stampaPostOrder (ABR t, STAMPA stamp)
    {
        if (t==NULL) return;
    
        if (t->sx!=NULL) abr_stampaPostOrder(t->sx,stamp);
        if(t->dx!=NULL) abr_stampaPostOrder(t->dx,stamp);
        stamp(t->info);
    
        return;
    
    }
    
    ABR abr_cancel(ABR t, void *elem, COMPARE compare)
    {
        if (t==NULL) return t;
    
        if (compare(elem,t->info)<0)
            t->sx=abr_cancel(t->sx,elem,compare);
        else if (compare(elem,t->info)>0)
            t->dx=abr_cancel(t->dx,elem,compare);
        else
            t=abr_cancellanodo(t);
    
        return t;
    }
    
    ABR abr_cancellanodo(ABR t)
    {
        ABR tmp=(abr *)malloc(sizeof(abr));
        tmp=t;
        if(tmp->sx == NULL) t=tmp->dx;
        else if (tmp->dx == NULL) t=tmp->sx;
        else
        {
             tmp=abr_staccamin(t,t->dx);
             t->info=tmp->info;
             }
    
        free(tmp);
        return t;
    }
    
    ABR abr_staccamin(ABR p, ABR t)
    {
        if (t!=NULL)
        {
                    if (t->sx!=NULL) return abr_staccamin(t,t->sx);
                    else
                    {
                        if (t==p->sx) p->sx=t->dx;
                        else p->dx=t->dx;
                        }
        }
    
    return t;
    }
    
    ABR abr_svuota (ABR t)
    {
    
        if (t!=NULL)
        {
            t->sx=abr_svuota(t->sx);
            t->dx=abr_svuota(t->dx);
    
            t=abr_cancellanodo(t);
        }
    return t;
    }
    
    dati.h
    #ifndef DATI_H_INCLUDED
    #define DATI_H_INCLUDED
    
    #include "datoINT.h"
    #include "datoSTRING.h"
    #include "datoFLOAT.h"
    #include "datoCHAR.h"
    
    
    #endif // DATI_H_INCLUDED
    datoINT.h
    #ifndef DATOINT_H_INCLUDED
    #define DATOINT_H_INCLUDED
    
    int compareINT(void * a, void * b);
    int * getInputINT (void);
    int * getRandomInt (void);
    void stampaINT (void * a);
    
    #endif // DATOINT_H_INCLUDED
    datoINT.c
    #include <stdio.h>
    #include <stdlib.h>
    #include "datoINT.h"
    
    int compareINT (void * a, void * b)
    {
        int a1= *(int*) a;
        int b1= *(int*) b;
        return a1-b1;
    }
    
    int * getInputINT (void)
    {
        int *in;
        in = (int *)malloc(sizeof(int));
        if(in == NULL){
            printf("Error: allocation int failed\n");
            exit(-1);
        }
        printf("Inserisci un valore intero:");
        scanf("%d", in);
        return in;
    }
    
    int * getRandomInt (void)
    {
        int *d;
        d = (int *)malloc(sizeof(int));
        if(d == NULL){
            printf("Error: allocation int failed\n");
            exit(-1);
        }
        *d = (rand()%100) ;
        return d;
    }
    
    void stampaINT (void * a)
    {
        int a1= *(int*) a;
        printf("%d\n", a1);
    }
    
    datoFLOAT.h
    #ifndef DATOFLOAT_H_INCLUDED
    #define DATOFLOAT_H_INCLUDED
    
    int compareFLOAT (void * a, void * b);
    float * getInputFLOAT (void);
    float * getRandomFLOAT (void);
    void stampaFLOAT (void * a);
    
    #endif // DATOFLOAT_H_INCLUDED
    datoFLOAT.c
    #include <stdio.h>
    #include <stdlib.h>
    #include "datoFLOAT.h"
    
    int compareFLOAT (void * a, void * b)
    {
        float a1= *(float*) a;
        float b1= *(float*) b;
        if((a1-b1)<0) return -1;
        if((a1-b1)>0) return 1;
        else return 0;
    }
    
    float * getInputFLOAT (void)
    {
        float *in;
        in = (float *)malloc(sizeof(float));
        if(in == NULL){
            printf("Error: allocation int failed\n");
            exit(-1);
        }
        printf("Inserisci un valore float:");
        scanf("%f.3", in);
        return in;
    }
    
    float * getRandomFLOAT (void)
    {
        float *d;
        d = (float *)malloc(sizeof(float));
        if(d == NULL){
            printf("Error: allocation int failed\n");
            exit(-1);
        }
        *d = (rand()%100) ;
        return d;
    }
    
    void stampaFLOAT (void * a)
    {
        float a1= *(float*) a;
        printf("%f.3\n", a1);
    }
    datoCHAR.h
    #ifndef DATOCHAR_H_INCLUDED
    #define DATOCHAR_H_INCLUDED
    
    int compareCHAR (void * a, void * b);
    char * getInputCHAR (void);
    char * getRandomCHAR (void);
    void stampaCHAR (void * a);
    
    #endif // DATOCHAR_H_INCLUDED
    datoCHAR.c
    #include <stdio.h>
    #include <stdlib.h>
    #include "datoCHAR.h"
    
    int compareCHAR (void * a, void * b)
    {
        int a1= *(int*) a;
        int b1= *(int*) b;
        return a1-b1;
    }
    
    char * getInputCHAR(void)
    {
        char *in;
        in = (char *)malloc(sizeof(char));
    
        printf("Inserisci un carattere: ");
        scanf("%c", in);
        return in;
    }
    
    char * getRandomCHAR (void)
    {
        char *d;
        d = (char *)malloc(sizeof(char));
    
        *d = (rand()%100) ;
        return d;
    }
    
    void stampaCHAR (void * a)
    {
        char a1= *(char*) a;
        printf("%c\n", a1);
    }
    
    datoSTRING.h
    #ifndef DATOSTRING_H_INCLUDED
    #define DATOSTRING_H_INCLUDED
    
    int compareSTRING (void* a, void*b);
    char * getInputSTRING (void);
    void stampaSTRING (void * a);
    char * getRandomSTRING (int n);
    
    #endif // DATOSTRING_H_INCLUDED
    datoSTRING.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "datoSTRING.h"
    
    int compareSTRING (void* a, void*b)
    {
        char* a1= (char *) a;
        char* b1= (char *) b;
        return strcmp(a1,b1);
    }
    
    char * getInputSTRING (void)
    {
        char *in;
        in = (char*)malloc(sizeof(char));
        if(in == NULL){
            printf("Error: allocation string failed\n");
            exit(-1);
        }
        printf("Inserisci una stringa:");
        scanf("%s", in);
    
        return in;
    }
    
    char * getRandomSTRING (int n)
    {
        int i,c;
        char *str=(char*)malloc(sizeof(char)*(n+1));
        for(i=0;i<n;i++)
            {
                c=97+(rand()%25);
                *(str+i)=(char) c;
                }
        *(str+n)='\0';
    
    return str;
    }
    
    void stampaSTRING (void * a)
    {
        char *a1= (char*) a;
        printf("%s\n", a1);
    }
    main.c
    #include <stdio.h>
    #include <stdlib.h>
    #include "abrgenerico.h"
    #include "dati.h"
    
    int main()
    {
        int n;
        ABR albero=NULL;
        int *datoi; char *datos, *datoc; float *datof;
        int i;
        int sceltatipo;
        int scelta;
        int sceltains;
    
        printf("COSTRUISCI ABR.\n\n");
    
        istr1:printf("Scegli il tipo di dati\n");
        printf("1) Intero.\n");
        printf("2) Float.\n");
        printf("3) Carattere.\n");
        printf("4) Stringa\n");
        printf("5) Struct.\n\n");
        scanf("%d",&sceltatipo);
        printf("Quanti elementi vuoi inserire?");
        scanf("%d",&n);
        printf("1- Inserisci dati casuali;\n2- Inserisci dati manualmente\n");
        scanf("%d",&sceltains);
        switch (sceltatipo)
        {
        case 1:
            for (i=0;i<n;i++)
            {
                if (sceltains==1) datoi=getRandomInt();
                else if(sceltains==2) datoi=getInputINT();
                albero=abr_insert(albero,(void*)datoi, compareINT);
    
            }
            abr_stampaInOrder(albero, stampaINT);
            goto istr2;
        case 2:
            for (i=0;i<n;i++)
            {
                if (sceltains==1) datof=getRandomFLOAT();
                else if(sceltains==2) datof=getInputFLOAT();
                albero=abr_insert(albero,(void*)datof, compareFLOAT);
    
            }
            abr_stampaInOrder(albero, stampaFLOAT);
            goto istr2;
        case 3:
            for (i=0;i<n;i++)
            {
                if (sceltains==1) datoc=getRandomCHAR();
                else if(sceltains==2) datoc=getInputCHAR();
                albero=abr_insert(albero,(void*)datoc, compareCHAR);
    
            }
            abr_stampaInOrder(albero, stampaCHAR);
            goto istr2;
        case 4:
            for (i=0;i<n;i++)
            {
                if (sceltains==1) {int x=rand()%10; datos=getRandomSTRING(x);}
                else if (sceltains==2) datos=getInputSTRING();
                albero=abr_insert(albero,(void*)datos, compareSTRING);
    
            }
            abr_stampaInOrder(albero, stampaSTRING);
            goto istr2;
        case 5:
        default:
            printf("::ERRORE:: Scelta non valida!");
            goto istr1;
        }
    
        istr2:printf("\n1) Visualizza Abr.\n");
        printf("2) Cancella Abr.\n");
        printf("3) Cancella un nodo dell'Abr.\n");
        scanf("%d",&scelta);
    
        switch(scelta)
        {
        case 1:
            if (albero==NULL) printf("Albero vuoto!\n");
    
            else if (sceltatipo==1)
                abr_stampaInOrder(albero,stampaINT);
            else if (sceltatipo==2)
                abr_stampaInOrder(albero,stampaFLOAT);
            else if (sceltatipo==3)
                abr_stampaInOrder(albero,stampaCHAR);
            else if (sceltatipo==4)
                abr_stampaInOrder(albero,stampaSTRING);
            goto istr2;
        case 2:
            albero=abr_svuota(albero);
            goto istr2;
        case 3:
            printf("Abr salvato:\n");
            if (sceltatipo==1)
                abr_stampaInOrder(albero,stampaINT);
            else if (sceltatipo==2)
                abr_stampaInOrder(albero,stampaFLOAT);
            else if (sceltatipo==3)
                abr_stampaInOrder(albero,stampaCHAR);
            else if (sceltatipo==4)
                abr_stampaInOrder(albero,stampaSTRING);
    
            printf("\nScelta nodo da cancellare... \n");
            if (sceltatipo==1)
                {datoi=getInputINT();
                albero=abr_cancel(albero,(void*)datoi,compareINT);
                printf("Abr dopo la cancellazione:\n");
                abr_stampaInOrder(albero,stampaINT);}
            if(sceltatipo==2)
                {datof=getInputFLOAT();
                albero=abr_cancel(albero,(void*)datof,compareFLOAT);
                printf("Abr dopo la cancellazione:\n");
                abr_stampaInOrder(albero,stampaFLOAT);}
            if(sceltatipo==3)
                {datoc=getInputCHAR();
                albero=abr_cancel(albero,(void*)datoc,compareCHAR);
                printf("Abr dopo la cancellazione:\n");
                abr_stampaInOrder(albero,stampaCHAR);}
            else if (sceltatipo==4)
                {datos=getInputSTRING();
                albero=abr_cancel(albero,(void*)datos,compareSTRING);
                printf("Abr dopo la cancellazione:\n");
                abr_stampaInOrder(albero,stampaSTRING);}
            goto istr2;
        }
    
        return 0;
    }
    
  • Re: Consiglio Manuali-ListaDoppiamentePuntata tipo dato generico

    Attento: il codice che hai scritto, sia in getInputCHAR, sia in getRandomCHAR ti considera tutti i caratteri ASCII, è proprio quello che vuoi?
    
    char * getInputCHAR(void) {
        char *in;
        in = (char *)malloc(sizeof(char));
        /* Altrimenti il carattere "a capo" lo considera un carattere
        fflush(stdin);
        printf("Inserisci un carattere: ");
        scanf("%c", in);
    
        return in;
    }
    
    Quel main con tutti quei goto? Perchè mai?
    E' assolutamente da ristrutturare. E' una pessima abitudine di programmazione quella di inserire i goto. E non è solo un mio punto di vista. Costa poco scrivere codice più leggibile e manutenibile.

    Le funzioni cancella non penso funzionino correttamente, produrranno una serie di memory leaks.
  • Re: Consiglio Manuali-ListaDoppiamentePuntata tipo dato generico

    Quel main con tutti quei goto? Perchè mai?
    E' assolutamente da ristrutturare. E' una pessima abitudine di programmazione quella di inserire i goto. E non è solo un mio punto di vista. Costa poco scrivere codice più leggibile e manutenibile.
    Ho inserito i goto semplicemente per non fare tanti switch uno dentro l'altro visto che richiedo si passi da un menu all'altro.. ritornando indietro con il codice.. Non sapevo fosse così sconsigliato sinceramente, è la prima volta che programmo dei main un po' più complessi..
  • Re: Consiglio Manuali-ListaDoppiamentePuntata tipo dato generico

    Le funzioni cancella non penso funzionino correttamente, produrranno una serie di memory leaks.
    A quale ti riferisci? abr_cancel l'ho provata fin ora per int, float e string e funziona..
  • Re: Consiglio Manuali-ListaDoppiamentePuntata tipo dato generico

    La libreria non conosce il dato, quindi non può deallocare. Le free che scrivi in realtà hanno come effetto quello di farti perdere i riferimenti ma nello heap lasciano intatto il dato. Fenomeno conosciuto come memory leak. Problema che ha un importante impatto sulla memoria.
  • Re: Consiglio Manuali-ListaDoppiamentePuntata tipo dato generico

    Le free che scrivi in realtà hanno come effetto quello di farti perdere i riferimenti ma nello heap lasciano intatto il dato.
    E quindi non posso usare una variabile temporanea per la cancellazione del nodo? perchè io in quel caso libero la memoria, o credevo di farlo.. deallocando il nodo di tipo ABR , indipendente, credevo, dal tipo di dato..
  • Re: Consiglio Manuali-ListaDoppiamentePuntata tipo dato generico

    Infatti. Non è coretto deallocare così. Poi perché mai dovresti allocare una nuova variabile per deallocare il nodo. Per imparare a deallocare correttamente, prova a scrivere a prescindere da questo esercizio una struct studente con nome, cognome, matricola, strct voto i campi sono: char *materia, int voto. Tutto allocato dinamicamente. Alloca questa struct e poi deallocala, se vuoi posta il codice di allocazione e deallocazione che verifichiamo insieme.
Devi accedere o registrarti per scrivere nel forum
75 risposte