Torna indietro   Hardware Upgrade Forum > Software > Programmazione

PC Specialist Lafité 14 AI AMD: assemblato come vuoi tu
PC Specialist Lafité 14 AI AMD: assemblato come vuoi tu
Il modello "build to order" di PCSpecialist permette di selezionare una struttura base per un sistema, personalizzandolo in base alle specifiche esigenze con una notevole flessibilità di scelta tra i componenti. Il modello Lafité 14 AI AMD è un classico notebook clamshell compatto e potente, capace di assicurare una elevata autonomia di funzionamento anche lontano dalla presa di corrente
Recensione Nothing Phone 4(a): sempre iconico ma ora più concreto
Recensione Nothing Phone 4(a): sempre iconico ma ora più concreto
Nothing con il suo nuovo Phone 4(a) conferma la sua identità visiva puntando su una costruzione che nobilita il policarbonato. La trasparenza resta l'elemento cardine, arricchita da una simmetria interna curata nei minimi dettagli. Il sistema Glyph si evolve, riducendosi nelle dimensioni ma aumentando l'utilità quotidiana grazie a nuove funzioni software integrate e notifiche visive. Ecco tutti i dettagli nella recensione completa
Corsair Vanguard Air 99 Wireless: non si era mai vista una tastiera gaming così professionale
Corsair Vanguard Air 99 Wireless: non si era mai vista una tastiera gaming così professionale
Nelle ultime settimane abbiamo provato la Corsair Vanguard Air 99 Wireless, una tastiera tecnicamente da gaming, ma che in realtà offre un ampio ventaglio di possibilità anche al di fuori delle sessioni di gioco. Flessibilità e funzionalità sono le parole d'ordine di una periferica che si rivolge a chi cerca un prodotto capace di adattarsi a ogni esigenza e ogni piattaforma
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 02-11-2015, 15:22   #1
danisrcnl
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 se risolvo intanto vi faccio sapere grazie!

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);

}
danisrcnl è offline   Rispondi citando il messaggio o parte di esso
Old 02-11-2015, 15:36   #2
sottovento
Senior Member
 
L'Avatar di sottovento
 
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
sottovento è offline   Rispondi citando il messaggio o parte di esso
Old 02-11-2015, 15:38   #3
danisrcnl
Junior Member
 
Iscritto dal: Nov 2015
Messaggi: 10
Quote:
Originariamente inviato da sottovento Guarda i messaggi
E' necessario sapere la definizione di studente; altrimenti si tratta di divinazione
Hai ragione

Codice:
typedef struct Item
{
    char *matricola;
    char *nome;
    char *cognome;
    struct
    {
        int giorno;
        int mese;
        int anno;
    }data;
    char sesso;
}studente;
danisrcnl è offline   Rispondi citando il messaggio o parte di esso
Old 02-11-2015, 15:44   #4
sottovento
Senior Member
 
L'Avatar di sottovento
 
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
sottovento è offline   Rispondi citando il messaggio o parte di esso
Old 02-11-2015, 15:46   #5
danisrcnl
Junior Member
 
Iscritto dal: Nov 2015
Messaggi: 10
Quote:
Originariamente inviato da sottovento Guarda i messaggi
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
Ci sono altre duecento righe che non ti ho mostrato, le memorie per ogni stringa o qualsiasi cosa sia sono allocate tutte, altrimenti non funzionerebbero le altre dieci funzioni che ho scritto 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.
danisrcnl è offline   Rispondi citando il messaggio o parte di esso
Old 02-11-2015, 15:53   #6
sottovento
Senior Member
 
L'Avatar di sottovento
 
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
Quote:
Originariamente inviato da danisrcnl Guarda i messaggi
Ci sono altre duecento righe che non ti ho mostrato, le memorie per ogni stringa o qualsiasi cosa sia sono allocate tutte, altrimenti non funzionerebbero le altre dieci funzioni che ho scritto 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.

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
sottovento è offline   Rispondi citando il messaggio o parte di esso
Old 02-11-2015, 15:57   #7
danisrcnl
Junior Member
 
Iscritto dal: Nov 2015
Messaggi: 10
Quote:
Originariamente inviato da sottovento Guarda i messaggi
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...
La cosa a cui mi fai pensare ora è che forse non ho aggiustato le allocazioni dopo aver fatto passare la funzione dalla ricezione by value del DB alla ricezione by reference, visto che stupidamente avevo passato tutto come nelle altre funzioni. Ora vedo se aggiustando questa cosa funzione l'importante è che quello che ho scritto sopra sia giusto!
danisrcnl è offline   Rispondi citando il messaggio o parte di esso
Old 02-11-2015, 16:04   #8
danisrcnl
Junior Member
 
Iscritto dal: Nov 2015
Messaggi: 10
Quote:
Originariamente inviato da sottovento Guarda i messaggi
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...
Ok ora l'assegnazione locale a db infatti funziona , solo credo che ci sia qualche errore nel'ultimo passaggio visto che ora ho un crash dopo tutte le gets ahah
danisrcnl è offline   Rispondi citando il messaggio o parte di esso
Old 02-11-2015, 16:08   #9
sottovento
Senior Member
 
L'Avatar di sottovento
 
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
Quote:
Originariamente inviato da danisrcnl Guarda i messaggi
Ok ora l'assegnazione locale a db infatti funziona , solo credo che ci sia qualche errore nel'ultimo passaggio visto che ora ho un crash dopo tutte le gets ahah
Bene.
Se hai ancora un crash, prova a postare la nuova versione...
__________________
In God we trust; all others bring data
sottovento è offline   Rispondi citando il messaggio o parte di esso
Old 02-11-2015, 16:10   #10
danisrcnl
Junior Member
 
Iscritto dal: Nov 2015
Messaggi: 10
Quote:
Originariamente inviato da sottovento Guarda i messaggi
Bene.
Se hai ancora un crash, prova a postare la nuova versione...
Il problema l'ho capito: non riallocavo anche nel vettore vero e proprio, ossia allocavo solo per la funzione locale, ho messo una bozza dell'allocazione in database, ma l'ho scritta male visto che qualche errore qui sopra, sicuramente ho gestito male i puntatori a database, ora te la mostro tutta la funzione:

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);

}
danisrcnl è offline   Rispondi citando il messaggio o parte di esso
Old 02-11-2015, 16:21   #11
sottovento
Senior Member
 
L'Avatar di sottovento
 
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
Codice:
    *database[i]=db;
}
Purtroppo la copia non puo' essere fatta cosi': all'interno della tua struttura le stringhe sono puntatori ad altra locazione (che fra l'altro vai a deallocare).
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
sottovento è offline   Rispondi citando il messaggio o parte di esso
Old 02-11-2015, 17:18   #12
danisrcnl
Junior Member
 
Iscritto dal: Nov 2015
Messaggi: 10
Quote:
Originariamente inviato da sottovento Guarda i messaggi
Codice:
    *database[i]=db;
}
Purtroppo la copia non puo' essere fatta cosi': all'interno della tua struttura le stringhe sono puntatori ad altra locazione (che fra l'altro vai a deallocare).
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.
Non saprei, in realtà l'operazione non mi sembra del tutto erronea, nel senso che copio in una struct un'altra struct dello stesso tipo, come ho fatto, ad esempio nelle funzioni di ordinamento. Al di la di questo, ignorando questo discorso, se volessi allocare correttamente nuova memoria per database[i] dalla funzione e non dal main come dovrei fare? Visto che ho un errore in fase di build su quelle righe?
danisrcnl è offline   Rispondi citando il messaggio o parte di esso
Old 03-11-2015, 08:33   #13
sottovento
Senior Member
 
L'Avatar di sottovento
 
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
Quote:
Originariamente inviato da danisrcnl Guarda i messaggi
Non saprei, in realtà l'operazione non mi sembra del tutto erronea, nel senso che copio in una struct un'altra struct dello stesso tipo, come ho fatto, ad esempio nelle funzioni di ordinamento. Al di la di questo, ignorando questo discorso, se volessi allocare correttamente nuova memoria per database[i] dalla funzione e non dal main come dovrei fare? Visto che ho un errore in fase di build su quelle righe?
No, in realta' quando copi la struttura lo fai copiando campo per campo, non allocando nuova memoria per le stringhe e copiandone il contenuto: copi semplicemente l'indirizzo, quindi la struttura di partenza e di arrivo puntano alla stessa copia delle stringhe allocate. Quando vai a deallocarle fai in modo che entrambe le strutture puntino ad un valore invalido e vai in crash.

Che errore hai in fase di build?
__________________
In God we trust; all others bring data
sottovento è offline   Rispondi citando il messaggio o parte di esso
Old 06-11-2015, 11:02   #14
danisrcnl
Junior Member
 
Iscritto dal: Nov 2015
Messaggi: 10
Quote:
Originariamente inviato da sottovento Guarda i messaggi
No, in realta' quando copi la struttura lo fai copiando campo per campo, non allocando nuova memoria per le stringhe e copiandone il contenuto: copi semplicemente l'indirizzo, quindi la struttura di partenza e di arrivo puntano alla stessa copia delle stringhe allocate. Quando vai a deallocarle fai in modo che entrambe le strutture puntino ad un valore invalido e vai in crash.

Che errore hai in fase di build?
Oggi dopo lezione provo a modificarla in modo da scrivere direttamente sul mio database[i] senza struct d'appoggio.
danisrcnl è offline   Rispondi citando il messaggio o parte di esso
Old 07-11-2015, 12:45   #15
danisrcnl
Junior Member
 
Iscritto dal: Nov 2015
Messaggi: 10
Quote:
Originariamente inviato da sottovento Guarda i messaggi
No, in realta' quando copi la struttura lo fai copiando campo per campo, non allocando nuova memoria per le stringhe e copiandone il contenuto: copi semplicemente l'indirizzo, quindi la struttura di partenza e di arrivo puntano alla stessa copia delle stringhe allocate. Quando vai a deallocarle fai in modo che entrambe le strutture puntino ad un valore invalido e vai in crash.

Che errore hai in fase di build?
Ecco qui la funzione un po' più raffinata, nessun errore in fase di build ed esecuzione, almeno apparentemente, sintatticamente corretta, ma nello stampare il database dopo l'aggiunta, nell'elenco ho, al suo indice, un (null) (null) (null) 0/0/0, praticamente come se non avesse memorizzato nulla.

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)++;
}
danisrcnl è offline   Rispondi citando il messaggio o parte di esso
Old 07-11-2015, 16:38   #16
danisrcnl
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
danisrcnl è offline   Rispondi citando il messaggio o parte di esso
Old 14-11-2015, 14:02   #17
fano
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!
fano è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


PC Specialist Lafité 14 AI AMD: assemblato come vuoi tu PC Specialist Lafité 14 AI AMD: assemblat...
Recensione Nothing Phone 4(a): sempre iconico ma ora più concreto Recensione Nothing Phone 4(a): sempre iconico ma...
Corsair Vanguard Air 99 Wireless: non si era mai vista una tastiera gaming così professionale Corsair Vanguard Air 99 Wireless: non si era mai...
Ecovacs DEEBOT T90 PRO OMNI: ora il rullo di lavaggio è ampio Ecovacs DEEBOT T90 PRO OMNI: ora il rullo di lav...
Recensione Samsung Galaxy S26 Ultra: finalmente qualcosa di nuovo Recensione Samsung Galaxy S26 Ultra: finalmente ...
12 MW e oltre 20.000 pannelli: Stellanti...
Sono bastate solo 5 ore per insegnare a ...
Fastweb + Vodafone e TIM: un accordo per...
Scaleway apre una nuova cloud region a M...
Il PC non dà accesso al disco C:/...
Attenzione alle app IPTV: nascondono Per...
Controller Xbox in offerta su Amazon: co...
vivo X300 Pro 5G a 1.199€ su Amazon: il ...
"Portraits of Italians": la ca...
Roborock Qrevo Curv 2 Pro crolla di prez...
Uber ha trovato il partner per i robotax...
Sony pronta a dire addio al marchio PSN:...
ARCTIC Senza AI 370: il PC 'sotto la scr...
Corsair 3200D, il mid-tower sotto i 100€...
Esiste un SSD NVMe M.2 2280 da 16 TB, ma...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 22:09.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v