[c][c++] funzione realloc non copia i dati
Inviato: 18 nov 2009, 20:06
Questo è il programma, non è cortissimo ma ci son parecchi commenti
ora quando inserisco 10 studenti consecutivamente e dunque si arriva dopo il decimo ad aumentare di 10 la dimensione dell'array mediante realloc l'output è questo:
quando metto il decimo e mostro il contenuto della zona di memoria dedicata all'array si vede che gli studenti dal secondo al nono mancano, come se la realloc mi copiasse solo la prima cella.
il tutto si trova nella funzione insertAStudent ed in particolare queste sono le istruzioni imputate:
boh!
- Codice: Seleziona tutto
#import <iostream>
#import <limits>
#import <stdio.h>
#import <malloc.h>
using namespace std;
struct materia
{
char nome[50];
char docente[50];
unsigned char voto;
};
struct studente
{
char nome[50];
unsigned int matricola;
materia esami[];
unsigned char media;
};
struct esame
{
unsigned int data;
int voto;
struct studente students;
struct materia subject;
};
unsigned int askChoices();
void insertAStudent (studente *&arrayOfStudents, studente *&lastStudent,
long unsigned int *numberOfStudents, long unsigned int *arrayOfStudentsLength);
void insertASubject (materia *&arrayOfSubjects, materia *&lastSubject,
long unsigned int *numberOfSubjects, long unsigned int *arrayOfSubjectsLength);
void viewStudents(studente *arrayOfStudents, long unsigned int *numberOfStudents);
void viewSubjects (materia *arrayOfSubjects, long unsigned int *numberOfSubjects);
int main()
{
unsigned int choice;
//primo elemento dell'array di studenti
studente *arrayOfStudents = (studente *) malloc(sizeof(studente)*10);
long unsigned int arrayOfStudentsLength =10;
//ultimo elemento +1 dell'array di studenti, per ora coincide con il primo
studente *lastStudent = arrayOfStudents;
//numero totale di studenti
long unsigned int numberOfStudents = 0;
//primo elemento dell'array di materie
materia *arrayOfSubjects = (materia *) malloc(sizeof(materia)*10); //array di 10 elementi
long unsigned int arrayOfSubjectsLength =10;
//ultimo elemento +1 dell'array di materie, per ora coincide con il primo
materia *lastSubject = arrayOfSubjects;
//numero totale di materie
long unsigned int numberOfSubjects = 0;
do
{
choice = askChoices();
switch(choice)
{
case 0:
{
return 0;
break;
}
case 1:
{
insertAStudent(arrayOfStudents, lastStudent, &numberOfStudents, &arrayOfStudentsLength);
break;
}
case 2:
{
insertASubject(arrayOfSubjects, lastSubject, &numberOfSubjects, &arrayOfSubjectsLength);
break;
}
case 3:
{/*
esame exam;
cout << "Nome della materia:";
//cin >> subject.nome;
cout << "Docente:";
cin >> subject.docente;
break;*/
}
case 5:
{
viewStudents(arrayOfStudents, &numberOfStudents);
break;
}
case 6:
{
viewSubjects(arrayOfSubjects, &numberOfSubjects);
break;
}
}
}
while (choice != 0);
return 0;
}
/**
* visualizza le possibili scelte per l'utente
*/
unsigned int askChoices()
{
unsigned int choice;
bool error = false;
do
{
cout << "Effettua una scelta:" <<endl;
cout << "1 - Inserisci i dati di uno studente;" <<endl;
cout << "2 - Inserisci una materia;" <<endl;
cout << "3 - Inserisci i risultati di un esame per uno studente;" <<endl;
cout << "4 - Visualizza i voti di uno studente e la sua media;"<<endl;
cout << "5 - Visualizza tutti gli studenti inseriti;" <<endl;
cout << "6 - Visualizza tutte le materie inserite;" <<endl;
cout << "0 - Esci." <<endl;
cin >> choice;
if (!cin.good())
{
error = true;
cout << "Inserisci un valore corretto!" <<endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
}
while ((choice <0) | (choice > 6) | error);
return choice;
}
/**
* inserisce uno studente
*/
void insertAStudent (studente *&arrayOfStudents, studente *&lastStudent,
long unsigned int *numberOfStudents, long unsigned int *arrayOfStudentsLength)
{
studente student;
student.matricola = 0;
//leggo la matricola
cout << "\nInserisci la matricola dello studente:\n";
bool error;
do
{
error = false;
cin >> student.matricola;
if (!cin.good()) //un errore, ad esempio è stato digitato un carattere anzichè un numero
{
error = true;
cout << "\nInserisci un valore corretto per la metricola, \"0\" se vuoi uscire!";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
continue;
}
if (student.matricola == 0) //l'utente vuole uscire senza inserire uno studente
return;
for (long unsigned int i = 0; i < (*numberOfStudents); i ++) //verifico che la matricola non sia già presente
{
if ((*(arrayOfStudents + i*sizeof(student))).matricola == student.matricola) //la matricola è presente
{
error = true; //richiedi il reinserimento della matricola
cout << "\nQuesta matricola è già presente! Riprova, oppure inserisci \"0\" se vuoi uscire";
break;
}
}
}
while (error);
//matricola OK, leggo il nome e il cognome
printf("\nNome e cognome:\n");
cin.clear(); //ripulisco il buffer di input
cin.ignore(numeric_limits<streamsize>::max(), '\n');
int i = 0;
char c;
while (((c = getc(stdin)) != 10) & (i < 49)) //al massimo 49 caratteri e fino a quando non si digita INVIO
{
student.nome[i] = c; //leggo il carattere
i++;
}
student.nome[i]='\0'; //aggiungo il carattere di fine stringa
printf("\nHai inserito lo studente di nome %s e con matricola %u\n", student.nome, student.matricola);
//aumento la dimensione dell'array di una cella per accogliere un possibile futuro studente
if (*arrayOfStudentsLength == (*numberOfStudents +1))
{
cout << "Sposto l'array, vecchio indirizzo: "<< arrayOfStudents;
(*arrayOfStudentsLength)+= 10;
arrayOfStudents = (studente *) realloc(arrayOfStudents, sizeof(studente) * (*arrayOfStudentsLength) );
cout << " nuovo indirizzo: "<< arrayOfStudents << "\n";
cout << " nuovo indirizzo: "<< arrayOfStudents << "\n";
}
/* aggiorno il puntatore alla prossima cella libera in accordo con (l'eventuale)
* riposizionamento in memoria di arrayofstudents in occasione
* dell'utilizzo di realloc*/
lastStudent = arrayOfStudents + (*numberOfStudents) * sizeof(studente);
(*numberOfStudents)++; //aumento il numero degli studenti presenti
*lastStudent = student; //inserisco lo studente nel posto libero alla fine dell'array
//punta alla prossima cella libera
lastStudent+= sizeof(studente);
viewStudents(arrayOfStudents, numberOfStudents);
//pulisce il buffer
cin.clear();
}
/**
* inserisce una materia
*/
void insertASubject (materia *&arrayOfSubjects, materia *&lastSubject,
long unsigned int *numberOfSubjects, long unsigned int *arrayOfSubjectsLength)
{
materia subject;
cout << "Inserisci il nome della materia:" << endl;
int i = 0;
char c;
//tolgo dal buffer di input un eventuale \n già presente (altrimenti non entra nel ciclo)
cin.ignore(numeric_limits<streamsize>::max(), '\n');
while (((c = getc(stdin)) != 10) & (i < 49)) //al massimo 49 caratteri e fino a quando non si digita INVIO
{
subject.nome[i] = c; //leggo il carattere
i++;
}
subject.nome[i]='\0'; //aggiungo il carattere di fine stringa
//leggo il nome del docente
cout << "\nInserisci il nome del docente:\n"<< flush;
i = 0;
while (((c = getc(stdin)) != 10) & (i < 49)) //al massimo 49 caratteri e fino a quando non si digita INVIO
{
subject.docente[i] = c; //leggo il carattere
i++;
}
subject.docente[i]='\0'; //aggiungo il carattere di fine stringa
cout << "\nHai inserito la materia di nome " << subject.nome << " e con docente " << subject.docente << endl;
//aumento la dimensione dell'array di una cella per accogliere una possibile futura materia
if (*arrayOfSubjectsLength == (*numberOfSubjects +1))
{
*arrayOfSubjectsLength = *arrayOfSubjectsLength + 10;
arrayOfSubjects = (materia *) realloc(arrayOfSubjects, sizeof(materia) * (*arrayOfSubjectsLength) );
}
/* aggiorno il puntatore alla prossima cella libera in accordo con (l'eventuale)
* riposizionamento in memoria di arrayOfSubjects in occasione
* dell'utilizzo di realloc*/
lastSubject = arrayOfSubjects + (*numberOfSubjects) * sizeof(materia);
(*numberOfSubjects)++; //aumento il numero delle materie presenti
*lastSubject = subject; //inserisco la materia nel posto libero alla fine dell'array
//punta alla prossima cella libera
lastSubject+= sizeof(materia);
//pulisce il buffer
cin.clear();
}
/**
* visualizza tutti gli studenti sinora inseriti
*/
void viewStudents(studente *arrayOfStudents, long unsigned int *numberOfStudents)
{
for (long unsigned int i= 0; i < *(numberOfStudents); i++)
{
cout << "Matricola: "<< (*(arrayOfStudents + i*sizeof(studente))).matricola << '\n';
cout << "Nome e cognome: "<< (*(arrayOfStudents + i*sizeof(studente))).nome << '\n';
cout << "---------------------------------------------------------------------\n";
}
}
/**
* visualizza tutte le materie sinora inserite
*/
void viewSubjects (materia *arrayOfSubjects, long unsigned int *numberOfSubjects)
{
for (long unsigned int i= 0; i < *(numberOfSubjects); i++)
{
cout << "Materia: "<< (*(arrayOfSubjects + i*sizeof(materia))).nome << '\n';
cout << "Docente: "<< (*(arrayOfSubjects + i*sizeof(materia))).docente << '\n';
cout << "---------------------------------------------------------------------\n";
}
}
ora quando inserisco 10 studenti consecutivamente e dunque si arriva dopo il decimo ad aumentare di 10 la dimensione dell'array mediante realloc l'output è questo:
- Codice: Seleziona tutto
Effettua una scelta:
1 - Inserisci i dati di uno studente;
2 - Inserisci una materia;
3 - Inserisci i risultati di un esame per uno studente;
4 - Visualizza i voti di uno studente e la sua media;
5 - Visualizza tutti gli studenti inseriti;
6 - Visualizza tutte le materie inserite;
0 - Esci.
1
Inserisci la matricola dello studente:
1
Nome e cognome:
dsgdfg
Hai inserito lo studente di nome dsgdfg e con matricola 1
Matricola: 1
Nome e cognome: dsgdfg
---------------------------------------------------------------------
Effettua una scelta:
1 - Inserisci i dati di uno studente;
2 - Inserisci una materia;
3 - Inserisci i risultati di un esame per uno studente;
4 - Visualizza i voti di uno studente e la sua media;
5 - Visualizza tutti gli studenti inseriti;
6 - Visualizza tutte le materie inserite;
0 - Esci.
1
Inserisci la matricola dello studente:
2
Nome e cognome:
dfgdfg
Hai inserito lo studente di nome dfgdfg e con matricola 2
Matricola: 1
Nome e cognome: dsgdfg
---------------------------------------------------------------------
Matricola: 2
Nome e cognome: dfgdfg
---------------------------------------------------------------------
Effettua una scelta:
1 - Inserisci i dati di uno studente;
2 - Inserisci una materia;
3 - Inserisci i risultati di un esame per uno studente;
4 - Visualizza i voti di uno studente e la sua media;
5 - Visualizza tutti gli studenti inseriti;
6 - Visualizza tutte le materie inserite;
0 - Esci.
1
Inserisci la matricola dello studente:
3fdgdf
Nome e cognome:
dfgfdg
Hai inserito lo studente di nome dfgfdg e con matricola 3
Matricola: 1
Nome e cognome: dsgdfg
---------------------------------------------------------------------
Matricola: 2
Nome e cognome: dfgdfg
---------------------------------------------------------------------
Matricola: 3
Nome e cognome: dfgfdg
---------------------------------------------------------------------
Effettua una scelta:
1 - Inserisci i dati di uno studente;
2 - Inserisci una materia;
3 - Inserisci i risultati di un esame per uno studente;
4 - Visualizza i voti di uno studente e la sua media;
5 - Visualizza tutti gli studenti inseriti;
6 - Visualizza tutte le materie inserite;
0 - Esci.
1
Inserisci la matricola dello studente:
4
Nome e cognome:
dfgdfg
Hai inserito lo studente di nome dfgdfg e con matricola 4
Matricola: 1
Nome e cognome: dsgdfg
---------------------------------------------------------------------
Matricola: 2
Nome e cognome: dfgdfg
---------------------------------------------------------------------
Matricola: 3
Nome e cognome: dfgfdg
---------------------------------------------------------------------
Matricola: 4
Nome e cognome: dfgdfg
---------------------------------------------------------------------
Effettua una scelta:
1 - Inserisci i dati di uno studente;
2 - Inserisci una materia;
3 - Inserisci i risultati di un esame per uno studente;
4 - Visualizza i voti di uno studente e la sua media;
5 - Visualizza tutti gli studenti inseriti;
6 - Visualizza tutte le materie inserite;
0 - Esci.
1
Inserisci la matricola dello studente:
5
Nome e cognome:
dgfdgdf
Hai inserito lo studente di nome dgfdgdf e con matricola 5
Matricola: 1
Nome e cognome: dsgdfg
---------------------------------------------------------------------
Matricola: 2
Nome e cognome: dfgdfg
---------------------------------------------------------------------
Matricola: 3
Nome e cognome: dfgfdg
---------------------------------------------------------------------
Matricola: 4
Nome e cognome: dfgdfg
---------------------------------------------------------------------
Matricola: 5
Nome e cognome: dgfdgdf
---------------------------------------------------------------------
Effettua una scelta:
1 - Inserisci i dati di uno studente;
2 - Inserisci una materia;
3 - Inserisci i risultati di un esame per uno studente;
4 - Visualizza i voti di uno studente e la sua media;
5 - Visualizza tutti gli studenti inseriti;
6 - Visualizza tutte le materie inserite;
0 - Esci.
1
Inserisci la matricola dello studente:
6
Nome e cognome:
dfgdfgfd
Hai inserito lo studente di nome dfgdfgfd e con matricola 6
Matricola: 1
Nome e cognome: dsgdfg
---------------------------------------------------------------------
Matricola: 2
Nome e cognome: dfgdfg
---------------------------------------------------------------------
Matricola: 3
Nome e cognome: dfgfdg
---------------------------------------------------------------------
Matricola: 4
Nome e cognome: dfgdfg
---------------------------------------------------------------------
Matricola: 5
Nome e cognome: dgfdgdf
---------------------------------------------------------------------
Matricola: 6
Nome e cognome: dfgdfgfd
---------------------------------------------------------------------
Effettua una scelta:
1 - Inserisci i dati di uno studente;
2 - Inserisci una materia;
3 - Inserisci i risultati di un esame per uno studente;
4 - Visualizza i voti di uno studente e la sua media;
5 - Visualizza tutti gli studenti inseriti;
6 - Visualizza tutte le materie inserite;
0 - Esci.
1
Inserisci la matricola dello studente:
7
Nome e cognome:
fdgdfgdf
Hai inserito lo studente di nome fdgdfgdf e con matricola 7
Matricola: 1
Nome e cognome: dsgdfg
---------------------------------------------------------------------
Matricola: 2
Nome e cognome: dfgdfg
---------------------------------------------------------------------
Matricola: 3
Nome e cognome: dfgfdg
---------------------------------------------------------------------
Matricola: 4
Nome e cognome: dfgdfg
---------------------------------------------------------------------
Matricola: 5
Nome e cognome: dgfdgdf
---------------------------------------------------------------------
Matricola: 6
Nome e cognome: dfgdfgfd
---------------------------------------------------------------------
Matricola: 7
Nome e cognome: fdgdfgdf
---------------------------------------------------------------------
Effettua una scelta:
1 - Inserisci i dati di uno studente;
2 - Inserisci una materia;
3 - Inserisci i risultati di un esame per uno studente;
4 - Visualizza i voti di uno studente e la sua media;
5 - Visualizza tutti gli studenti inseriti;
6 - Visualizza tutte le materie inserite;
0 - Esci.
1
Inserisci la matricola dello studente:
8
Nome e cognome:
fdgdfgf
Hai inserito lo studente di nome fdgdfgf e con matricola 8
Matricola: 1
Nome e cognome: dsgdfg
---------------------------------------------------------------------
Matricola: 2
Nome e cognome: dfgdfg
---------------------------------------------------------------------
Matricola: 3
Nome e cognome: dfgfdg
---------------------------------------------------------------------
Matricola: 4
Nome e cognome: dfgdfg
---------------------------------------------------------------------
Matricola: 5
Nome e cognome: dgfdgdf
---------------------------------------------------------------------
Matricola: 6
Nome e cognome: dfgdfgfd
---------------------------------------------------------------------
Matricola: 7
Nome e cognome: fdgdfgdf
---------------------------------------------------------------------
Matricola: 8
Nome e cognome: fdgdfgf
---------------------------------------------------------------------
Effettua una scelta:
1 - Inserisci i dati di uno studente;
2 - Inserisci una materia;
3 - Inserisci i risultati di un esame per uno studente;
4 - Visualizza i voti di uno studente e la sua media;
5 - Visualizza tutti gli studenti inseriti;
6 - Visualizza tutte le materie inserite;
0 - Esci.
1
Inserisci la matricola dello studente:
9
Nome e cognome:
dfggfdg
Hai inserito lo studente di nome dfggfdg e con matricola 9
Matricola: 1
Nome e cognome: dsgdfg
---------------------------------------------------------------------
Matricola: 2
Nome e cognome: dfgdfg
---------------------------------------------------------------------
Matricola: 3
Nome e cognome: dfgfdg
---------------------------------------------------------------------
Matricola: 4
Nome e cognome: dfgdfg
---------------------------------------------------------------------
Matricola: 5
Nome e cognome: dgfdgdf
---------------------------------------------------------------------
Matricola: 6
Nome e cognome: dfgdfgfd
---------------------------------------------------------------------
Matricola: 7
Nome e cognome: fdgdfgdf
---------------------------------------------------------------------
Matricola: 8
Nome e cognome: fdgdfgf
---------------------------------------------------------------------
Matricola: 9
Nome e cognome: dfggfdg
---------------------------------------------------------------------
Effettua una scelta:
1 - Inserisci i dati di uno studente;
2 - Inserisci una materia;
3 - Inserisci i risultati di un esame per uno studente;
4 - Visualizza i voti di uno studente e la sua media;
5 - Visualizza tutti gli studenti inseriti;
6 - Visualizza tutte le materie inserite;
0 - Esci.
1
Inserisci la matricola dello studente:
10
Nome e cognome:
fdgdfgf
Hai inserito lo studente di nome fdgdfgf e con matricola 10
Sposto l'array, vecchio indirizzo: 0x9095008 nuovo indirizzo: 0x9095660
nuovo indirizzo: 0x9095660
Matricola: 1
Nome e cognome: dsgdfg
---------------------------------------------------------------------
Matricola: 0
Nome e cognome:
---------------------------------------------------------------------
Matricola: 0
Nome e cognome:
---------------------------------------------------------------------
Matricola: 0
Nome e cognome:
---------------------------------------------------------------------
Matricola: 0
Nome e cognome:
---------------------------------------------------------------------
Matricola: 0
Nome e cognome:
---------------------------------------------------------------------
Matricola: 0
Nome e cognome:
---------------------------------------------------------------------
Matricola: 0
Nome e cognome:
---------------------------------------------------------------------
Matricola: 0
Nome e cognome:
---------------------------------------------------------------------
Matricola: 10
Nome e cognome: fdgdfgf
---------------------------------------------------------------------
Effettua una scelta:
1 - Inserisci i dati di uno studente;
2 - Inserisci una materia;
3 - Inserisci i risultati di un esame per uno studente;
4 - Visualizza i voti di uno studente e la sua media;
5 - Visualizza tutti gli studenti inseriti;
6 - Visualizza tutte le materie inserite;
0 - Esci.
quando metto il decimo e mostro il contenuto della zona di memoria dedicata all'array si vede che gli studenti dal secondo al nono mancano, come se la realloc mi copiasse solo la prima cella.
il tutto si trova nella funzione insertAStudent ed in particolare queste sono le istruzioni imputate:
- Codice: Seleziona tutto
//aumento la dimensione dell'array di una cella per accogliere un possibile futuro studente
if (*arrayOfStudentsLength == (*numberOfStudents +1))
{
cout << "Sposto l'array, vecchio indirizzo: "<< arrayOfStudents;
(*arrayOfStudentsLength)+= 10;
arrayOfStudents = (studente *) realloc(arrayOfStudents, sizeof(studente) * (*arrayOfStudentsLength) );
cout << " nuovo indirizzo: "<< arrayOfStudents << "\n";
cout << " nuovo indirizzo: "<< arrayOfStudents << "\n";
}
/* aggiorno il puntatore alla prossima cella libera in accordo con (l'eventuale)
* riposizionamento in memoria di arrayofstudents in occasione
* dell'utilizzo di realloc*/
lastStudent = arrayOfStudents + (*numberOfStudents) * sizeof(studente);
(*numberOfStudents)++; //aumento il numero degli studenti presenti
*lastStudent = student; //inserisco lo studente nel posto libero alla fine dell'array
//punta alla prossima cella libera
lastStudent+= sizeof(studente);
viewStudents(arrayOfStudents, numberOfStudents);
boh!