Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1
    Utente di HTML.it
    Registrato dal
    Apr 2014
    Messaggi
    8

    [C]Deallocare matrice dinamica di struct

    Buongiorno, sto facendo il seguente codice in C (ho impostato anche il compilatore, Visual Studio 2010, per compilare in C). Ma quando arriva alla fine mi da questo errore:


    codice:
             Windows ha generato un punto di interruzione in Gestione Classe.exe.
    
    Ciò può essere dovuto a un danneggiamento dell'heap che indica un bug in Gestione Classe.exe o in una qualunque delle DLL che ha caricato.
    
    È anche possibile che l'utente abbia premuto F12 mentre Gestione Classe.exe era attivo.
    
    Controllare la finestra di output per ulteriori informazioni diagnostiche.


    Il codice è il seguente, ed ha la funzione di leggere un numero dinamico di classi ed allocarne per ognuno un numero dinamico di studenti. Lo avevo appena iniziato, adesso ha solo come compito notare che non esiste alcun file "matrice.dat" e far creare la prima classe. Ho utilizzato una matrice perchè appena capisco perchè mi da l'errore implementerò una lettura da file che leggerà tutte le classi e le disporrà sulla matrice.


    codice:
             #include <stdio.h>
    #include <stdlib.h>
    
    struct studente {
        char nome[20],cognome[20];
        int voto;
    };
    
    void allocaClasse(int,struct studente ***,int);
    void trasformaMaiuscola(int,struct studente***,int);
    void stampaClasse(int, struct studente ***,int);
    void liberaMemoria(int, struct studente***, int);
    
    void main(){
        struct studente **classi;
        FILE *fp;
        int nClassi,nStudenti,classeAttuale,i,j;
    
    
    
        fp=fopen("Classi.dat","rb+");
        if(fp==NULL){
            printf("Nessuna classe trovata, si procede alla creazione di una nuova.\nQuanti studenti ne fanno parte? ");
            scanf("%d",&nStudenti);
            nClassi=1;
            classeAttuale=0;
            allocaClasse(nStudenti,&classi,nClassi);
            trasformaMaiuscola(nStudenti,&classi,nClassi);
            stampaClasse(nStudenti,&classi,classeAttuale);
            for(i=0;i<nClassi;i++) free(classi[i]);
            free(classi); 
     }
        scanf("\n");
    }
    
    void allocaClasse(int A, struct studente ***B,int C){
        int i,j;
        (*B)=malloc(C*sizeof(struct studente*));
        for (i=0;i<C;i++) (*B)[i]=malloc(A*sizeof(struct studente*));
    
        for (i=0;i<C;i++) {
            for(j=0;j<A;j++){
                printf("Inserire il cognome dello studente %d: ",j);
                scanf("%s",&(*B)[i][j].cognome);
                printf("Inserire il nome dello studente %d: ",j);
                scanf("%s",&(*B)[i][j].nome);
                printf("Inserire il voto dello studente %d: ",j);
                scanf("%d",&(*B)[i][j].voto);
    
            }
        }
    }
    Ho omesso le funzioni stampa/trasforma maiuscola perchè non credo creino problemi, quindi era inutile appesantire qui il codice. Se servono le metto.
    Grazie

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,466
    Quando hai l'errore?
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Utente di HTML.it
    Registrato dal
    Apr 2014
    Messaggi
    8
    A fine programma, dopo che ha stampato.

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,466
    Intendi nelle righe

    for(i=0;i<nClassi;i++) free(classi[i]);
    free
    (classi);

    Se scrivi qualche printf prima e/o dopo, puoi identificare precisamente le linee.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    Utente di HTML.it
    Registrato dal
    Apr 2014
    Messaggi
    8
    Esattamente in quelle righe. Perchè mettendo un printf prima lo leggo, poi da l'errore e non stampa il printf subito dopo. Quindi il problema è in quelle righe.

  6. #6
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,466
    Intanto mi sembra che questa

    for (i=0;i<C;i++) (*B)[i]=(studente *)malloc(A*sizeof(struct studente*));

    debba essere

    for (i=0;i<C;i++) (*B)[i]=(studente *)malloc(A*sizeof(struct studente));
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  7. #7
    L'errore è piuttosto macroscopico, quanto tipico: stai allocando una quantità insufficiente di memoria.
    In particolare, con la linea di codice:

    codice:
    for (i=0;i<C;i++) (*B)[i]=malloc(A*sizeof(struct studente*));
    Stai erroneamente allocando memoria solo per un puntatore alla struttura da te definita, e non per l'intera struttura come invece è necessario. C'è un asterisco di troppo!

    Inoltre è fortemente consigliato (leggi: obbligatorio) tenere conto dei valori restituiti dalle malloc, le quali possono fallire restituendo un valore NULL, con tutto ciò che ne consegue. Allo stesso modo, è opportuno effettuare un cast esplicito dei valori restituiti dalle varie malloc().

    EDIT: cross posting con il buon Oregon... ;-)
    • Un plauso a Grisha Perelman, raro esempio di genuino anticonformismo umano e scientifico.

  8. #8
    Utente di HTML.it
    Registrato dal
    Apr 2014
    Messaggi
    8
    Innanzitutto grazie a entrambi per le risposte.
    Sto compilando il file (Main.c) come file C (impostato dalle impostazioni di Visual Studio) e ci è stato insegnato in aula che compilando in C il casting non è necessario, bensì è necessario in C++, è corretto? L'ho omesso per questo motivo, in quanto il professore non lo accetta in C puro.

    Riguardo l'asterisco, ho corretto in questo modo:
    codice:
    void allocaClasse(int A, struct studente ***B,int C){
        int i,j;
        *B=malloc(C*sizeof(struct studente*));
        for (i=0;i<C;i++) (*B)[i]=malloc(A*sizeof(struct studente));
    
        for (i=0;i<C;i++) 
            for(j=0;j<A;j++){
                printf("Inserire il cognome dello studente %d: ",j+1);
                scanf("%s",&(*B)[i][j].cognome);
                printf("Inserire il nome dello studente %d: ",j+1);
                scanf("%s",&(*B)[i][j].nome);
                printf("Inserire il voto dello studente %d: ",j+1);
                scanf("%d",&(*B)[i][j].voto);
    
            }
    }
    Ma l'errore si ripresenta nello stesso punto!
    Riguardo il controllo sulle malloc ti ringrazio del consiglio, metterò dei controlli. Comunque in questo caso non sta restituendo NULL in quanto la funzione stampa funziona.

  9. #9
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,466
    Per il cast va bene ... io l'ho aggiunto perché compilo in C++.

    Per il problema, elimina questa riga

    scanf("\n");

    e poi commenta le chiamate alle altre due funzioni


    /* trasformaMaiuscola(nStudenti,&classi,nClassi);
    stampaClasse
    (nStudenti,&classi,classeAttuale); */

    e controlla se il problema si presenta ancora

    No MP tecnici (non rispondo nemmeno!), usa il forum.

  10. #10
    Utente di HTML.it
    Registrato dal
    Apr 2014
    Messaggi
    8
    Quote Originariamente inviata da oregon Visualizza il messaggio
    Per il cast va bene ... io l'ho aggiunto perché compilo in C++.

    Per il problema, elimina questa riga

    scanf("\n");

    e poi commenta le chiamate alle altre due funzioni


    /* trasformaMaiuscola(nStudenti,&classi,nClassi);
    stampaClasse
    (nStudenti,&classi,classeAttuale); */

    e controlla se il problema si presenta ancora

    Sì avevo provato, per avere la certezza ora ho appena riprovato e l'errore continua a presentarsi..

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 © 2024 vBulletin Solutions, Inc. All rights reserved.