|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Junior Member
Iscritto dal: Nov 2015
Messaggi: 10
|
[C] Crash su gets()
Ciao a tutti, ho un piccolo problema con un programma che gestisce un database di studenti universitari implementando funzioni di ordinamento per nome o matricola, ricerca normale o dicotomica a seconda dei casi, cancellazione dal DB, etc nonchè l'aggiunta di uno studente al DB stesso, qui ho un crash fisso sulla prima gets() del codice che vi posto di seguito, è molto probabile che io abbia combinato qualche pasticcio con il passaggio by reference del vettore di struct, visto che sono un poco alle strette una mano nell'individuare in fretta il problema la gradirei molto
Codice:
int aggiungi(studente **database, int n, int i)
{
studente db;
int raddoppio=0;
if(n==i)
{
*database=(struct Item *)realloc(database, sizeof(struct Item)*2*n);
raddoppio=1;
}
printf("Inserisci la MATRICOLA (SXXXXXX): ");
gets(db.matricola);
printf("\nInserisci il NOME: ");
gets(db.nome);
printf("\nInserisci il COGNOME: ");
gets(db.cognome);
printf("\nInserisci la DATA di NASCITA (gg/mm/aaaa) : ");
scanf("%d/%d/%d", &db.data.giorno, &db.data.mese, &db.data.anno);
printf("\nInserisci il SESSO (M o F) : ");
while(getchar() != '\n');
scanf("%c", &db.sesso);
*database[i]=db;
return(raddoppio);
}
|
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
E' necessario sapere la definizione di studente; altrimenti si tratta di divinazione
__________________
In God we trust; all others bring data |
|
|
|
|
|
#3 |
|
Junior Member
Iscritto dal: Nov 2015
Messaggi: 10
|
|
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Non hai allocato memoria alcuna per matricola, nome e cognome. Sono solo puntatori al nulla.
Potresti decidere di assegnare loro una dimensione fissa e cambiare la definizione, per esempio, con char matricola[100]; cosi' avrai 100 caratteri a disposizione. Altrimenti lo puoi fare anche dinamicamente. Ci sono altri problemi nel tuo codice, ma e' meglio vederli dopo per evitare confusione
__________________
In God we trust; all others bring data |
|
|
|
|
|
#5 | |
|
Junior Member
Iscritto dal: Nov 2015
Messaggi: 10
|
Quote:
il problema deve essere nella scrittura sul database passato by reference, credo, visto che è una cosa che ho visto da poco e sicuramente ho fatto un po' di confusione.
|
|
|
|
|
|
|
#6 | |
|
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Quote:
Le 200 righe sono nella funzione che hai pubblicato? Se si, e' necessario vederle. Se no, il problema e' ancora quello perche' dichiari db di tipo studente e lo usi subito...
__________________
In God we trust; all others bring data |
|
|
|
|
|
|
#7 | |
|
Junior Member
Iscritto dal: Nov 2015
Messaggi: 10
|
Quote:
|
|
|
|
|
|
|
#8 | |
|
Junior Member
Iscritto dal: Nov 2015
Messaggi: 10
|
Quote:
|
|
|
|
|
|
|
#9 | |
|
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Quote:
Se hai ancora un crash, prova a postare la nuova versione...
__________________
In God we trust; all others bring data |
|
|
|
|
|
|
#10 | |
|
Junior Member
Iscritto dal: Nov 2015
Messaggi: 10
|
Quote:
Codice:
int aggiungi(studente **database, int n, int i)
{
studente db;
int raddoppio=0;
if(n==i)
{
*database=(struct Item *)realloc(database, sizeof(struct Item)*2*n);
raddoppio=1;
}
db.matricola=(char*)malloc(sizeof(char)*N);
db.nome=(char*)malloc(sizeof(char)*MAX);
db.cognome=(char*)malloc(sizeof(char)*MAX);
printf("Inserisci la MATRICOLA (SXXXXXX): ");while((getchar() != '\n') && (getchar() != ' '));
gets(db.matricola);
printf("\nInserisci il NOME: ");while((getchar() != '\n') && (getchar() != ' '));
gets(db.nome);
printf("\nInserisci il COGNOME: ");while((getchar() != '\n') && (getchar() != ' '));
gets(db.cognome);
printf("\nInserisci la DATA di NASCITA (gg/mm/aaaa) : ");
scanf("%d/%d/%d", &db.data.giorno, &db.data.mese, &db.data.anno);
printf("\nInserisci il SESSO (M o F) : ");
while(getchar() != '\n');
scanf("%c", &db.sesso);
/*
*database[i].matricola=(char*)malloc(sizeof(char)*N);
*database[i].nome=(char*)malloc(sizeof(char)*MAX);
*database[i].cognome=(char*)malloc(sizeof(char)*MAX);*/
*database[i]=db;
free(db.matricola);free(db.nome);free(db.cognome);
return(raddoppio);
}
|
|
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Codice:
*database[i]=db; } Dovresti farti una copia a mano ed eventualmente decidere cosa fare delle stringhe? Vuoi copiare l'intero contenuto? Allora devi allocare spazio in db e copiare. Vuoi copiare solo l'indirizzo, visto che e' valido? Allora non devi deallocare alla fine.
__________________
In God we trust; all others bring data |
|
|
|
|
|
#12 | |
|
Junior Member
Iscritto dal: Nov 2015
Messaggi: 10
|
Quote:
|
|
|
|
|
|
|
#13 | |
|
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Quote:
Che errore hai in fase di build?
__________________
In God we trust; all others bring data |
|
|
|
|
|
|
#14 | |
|
Junior Member
Iscritto dal: Nov 2015
Messaggi: 10
|
Quote:
|
|
|
|
|
|
|
#15 | |
|
Junior Member
Iscritto dal: Nov 2015
Messaggi: 10
|
Quote:
Codice:
void aggiungi(studente** p_database, int* p_allocati, int* p_usati)
{
if(*p_allocati==*p_usati)
{
*p_database=(struct Item*)realloc(*p_database, sizeof(struct Item)*2*(*p_allocati));
*p_allocati=2*(*p_allocati);
}
p_database[*p_usati]->nome=(char*)malloc(sizeof(char)*MAX);
p_database[*p_usati]->cognome=(char*)malloc(sizeof(char)*MAX);
p_database[*p_usati]->matricola=(char*)malloc(sizeof(char)*MAX);
getchar();
printf("\nInserisci il NOME: ");
gets(p_database[*p_usati]->nome);
printf("\nInserisci il COGNOME: ");
gets(p_database[*p_usati]->cognome);
printf("\nInserisci la MATRICOLA: ");
gets(p_database[*p_usati]->matricola);
printf("\nInserisci la data di nascita (gg/mm/aaaa): ");
scanf("%d/%d/%d", &(p_database[*p_usati]->data.giorno), &(p_database[*p_usati]->data.mese), &(p_database[*p_usati]->data.anno)); getchar();
printf("\nInserisci il SESSO: ");
scanf("%c", &(p_database[*p_usati]->sesso));
(*p_usati)++;
}
|
|
|
|
|
|
|
#16 |
|
Junior Member
Iscritto dal: Nov 2015
Messaggi: 10
|
Anche se in realtà il vettore database, anche se di struct, dovrebbe essere passato by reference alla funzione, proprio in quanto vettore, quindi dovrei aver fatto un casino inutile
|
|
|
|
|
|
#17 |
|
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2095
|
In ogni caso anche se riuscirai ad allocare la memoria per le tue stringhe ti sconsiglio vivamente di usare gets() per leggere da STDIN! Tu alla fine gli darai una dimensione fissa (poniamo 100 quindi allocare memoria non servirebbe a nulla falli array di 100 e via!) e cosa accade se l'utente mette 150 caratteri? Che nella tua stringa finiscono 150 caratteri senza alcun tappo ovvero una stringa sbordante e non valida
Quindi meglio usare fgets() a cui passi la dimensione massima dell'array e se l'utente passa più caratteri la stringa viene, semplicemente, troncata! |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 19:45.





















