Programma crasha se aggiungo più di un elemento al DB

stichtom

Utente Attivo
56
1
Ciao a tutti, sto facendo un esercizio per la gestione di un registro scolastico. L'ho finito e all'inizio sembrava funzionare correttamente. Poi mi sono accorto che se aggiungo più di uno studente al database, il programma crasha. In particolare ho notato che il problema è collegato in qualche modo al salvataggio del nome (forse qualcosa con la realloc), infatti se lavoro solo con i numeri delle matricole non c'è nessun problema.


Qualcuno potrebbe darmi una mano? Il codice completo (in particolare le funzioni add e print sono quelle interessate):


Codice:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>


#ifdef _WIN32
#define CLEAR "cls"
#else // Negli altri OS
#define CLEAR "clear"
#endif


#define CLEAR_BUFFER do { c = getchar(); } while (c != '\n' && c != EOF); // Macro per pulire il buffer in input
#define MAX 100 // Definisco il numero massimo di caratteri per il nome, cognome e indirizzo
#define TRUE 1
#define FALSE 0


typedef struct {
    int day;
    int month;
    int year;
} DATE_T;


typedef struct {
    int code;
    char *name;
    char *surname;
    char *address;
    DATE_T date;
    int *exams;
} STUDENT_T;


STUDENT_T *student;
char courses[][15] = {"Programmazione", "Inglese", "Analisi"}; // SISTEMARE POI
int myIndex = 0; // Contatore che conta il numero degli studenti


int checkValue(int value, int check, int min, int max);
void checkAllocation(STUDENT_T *student);
void menu();
void add(STUDENT_T *student);
void printDatabase(STUDENT_T *student);
char* readString();
void exitmenu();




int main()
{


    student = (STUDENT_T*) malloc(sizeof(STUDENT_T));
    checkAllocation(student);


    menu();


    free(student);


    return 0;
}


void menu()
{
    int menu, check;


    system(CLEAR);


    printf("\t\t ---- MENU GESTIONE SEGRETERIA ---- \n\n");
    printf("1 - Inserisci un nuovo studente\n");
    printf("2 - Stampa il registro\n");
    printf("3 - Elimina uno studente\n");
    printf("4 - Ricerca uno studente\n");
    printf("5 - Ricerca studenti per esami da sostenere\n");
    printf("6 - Esci dal programma\n\n");
    printf("Scegli un opzione dal menu: ");
    check = scanf("%d", &menu);
    menu = checkValue(menu, check, 1, 6);


    switch (menu) {
    case 1 :
        add(student);
        break;
    case 2 :
        printDatabase(student);
        break;
    case 3 :
        //cancel(student);
        break;
    case 4 :
        //search(student);
        break;
    case 5 :
        //searchSubject(student);
        break;
    case 6 :
        exit(EXIT_SUCCESS);
    default :
        printf("Errore, scelta non valida");
        exit(EXIT_FAILURE);
    }


    return;
}




int checkValue(int value, int check, int min, int max)
{
    int c;


    CLEAR_BUFFER
    while (value < min || value > max || check != 1) {
        printf("Errore, devi inserire un valore valido compreso tra %d e %d: ", min, max);
        check = scanf("%d", &value);
        CLEAR_BUFFER
    }


    return value;
}


void checkAllocation(STUDENT_T *student)
{
    if (student == NULL) {
        printf("Errore durante l'allocazione dinamica della memoria");
        exit(EXIT_FAILURE);
    }


    return;
}


void exitmenu()
{
    int option, check;


    printf("\n\nPremi 0 per tornare al main o 1 per uscire: ");
    check = scanf("%d", &option);
    option = checkValue(option, check, 0, 1);


    if (option == 0)
        menu();
    else if (option == 1)
        exit(EXIT_SUCCESS);
}


void add(STUDENT_T *student)
{


    char c;
    int check, j;
    int i = myIndex;
    /*enum subjects {Programmazione, Inglese, Analisi, Algoritmi, Architettura_Elaboratori, Algebra};
    enum subjects courses;*/
    system(CLEAR);


    student = (STUDENT_T*) realloc(student, (myIndex + 1) * sizeof(STUDENT_T));
    checkAllocation(student);


    printf("I: %d, INDEX = %d", i, myIndex);
    printf("\t\t ---- MENU GESTIONE SEGRETERIA ---- \n\n");
    printf("Inserisci il numero di matricola: ");
    check = scanf("%d", &student[i].code);
    student[i].code = checkValue(student[i].code, check, 0, INT_MAX);
    for (j = 0; j < myIndex; j++)
        if (student[i].code == student[j].code) {
            printf("Il numero di matricola inserito e\' gia presente nel database");
            exitmenu();
        }


    printf("Inserisci il nome: ");
    for (j = 0; j < MAX && (c = getchar()) != '\n'; j++) {
        student[i].name = (char*)realloc(student[i].name , (j+1) * sizeof(char));
        if (student[i].name  == NULL) {
            printf("Errore durante l'allocazione dinamica della memoria");
            exit(EXIT_FAILURE);
        }
        student[i].name[j] = c;
    }
    student[i].name[j] = '\0';


    // altri input 


    myIndex++;


    exitmenu();


    return;


}


void printDatabase(STUDENT_T *student)
{
    int i, j;


    system(CLEAR);


    printf("\t\t ---- VISUALIZZA CONTENUTO DATABASE ---- \n\n");
    printf("INDEX: %d\n\n", myIndex);
    if (myIndex == 0)
        printf("Non ci sono elementi da visualizzare nel database");
    else {
        for (i = 0; i < myIndex; i++) {
            printf("INDEX: %d, i: %d\n\n", myIndex, i);
            printf("Numero matricola: %d\n", student[i].code);
            printf("\tNome e Cognome: %s\n", student[i].name/*, student[i].surname*/);
           // Altre stampe


        }


    }


    exitmenu();


    return;


}
 

dijkstra91

Nuovo Utente
1
0
Ciao, il problema con il tuo programma è che la funzione add prende come parametro un puntatore a student (passato per valore). Perciò se la realloc alloca una nuova area di memoria, questa viene salvata solo nella variabile locale *student all'interno della funzione, ma la variabile globale student rimane inalterata (e punta ad una locazione di memoria non più allocata). Perciò, o all'interno della funzione modifichi direttamente la variabile globale, oppure devi passare un puntatore a puntatore.
 

Ci sono discussioni simili a riguardo, dai un'occhiata!

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili