Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Test ride Can-Am Origin: la moto elettrica che fa dimenticare il motore a scoppio (ma occhio all'autonomia)
Test ride Can-Am Origin: la moto elettrica che fa dimenticare il motore a scoppio (ma occhio all'autonomia)
Abbiamo provato per una settimana intera la Can-Am Origin, la Dual Sport elettrica del gruppo canadese BRP: ecco com'è andata tra città, autostrada e un primo assaggio di sterrato
Logitech G325, G305 e G316 X: il tris per chi non vuole rinunciare a nulla, spendendo poco
Logitech G325, G305 e G316 X: il tris per chi non vuole rinunciare a nulla, spendendo poco
Nelle ultime settimane abbiamo provato il mouse Logitech G305, la tastiera G316 X 98 e le cuffie G325. Si tratta del setup entry-level di Logitech che ormai, di "entry-level" ha ben poco. Tastiera e mouse offrono prestazioni di livello competitivo con quasi nessuna rinuncia e un livello di personalizzazione estremamente elevato. Le cuffie, invece, hanno mostrato qualche debolezza, ma propongono un ventaglio di funzionalità completo che consente di abbandonare completamente i cavi
Recensione POCO F9 pro: potenza da vero top di gamma, display da 185 Hz e finalmente una fotocamera da prendere sul serio
Recensione POCO F9 pro: potenza da vero top di gamma, display da 185 Hz e finalmente una fotocamera da prendere sul serio
POCO F9 Pro arriva sul mercato con l'obiettivo di portare prestazioni da smartphone top di gamma in una fascia di prezzo "più aggressiva", senza rinunciare a un comparto fotografico finalmente all'altezza. Dopo averlo testato sul campo, emerge uno smartphone molto più completo rispetto alla generazione precedente, ma anche con alcuni piccoli compromessi che diventano difficili da ignorare quando il prezzo di listino sfiora i 1.000 euro.
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 02-11-2015, 14: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, 14: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, 14: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, 14: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, 14: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, 14: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, 14: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, 15: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, 15: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, 15: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, 15: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, 16: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, 07: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, 10: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, 11: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, 15: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, 13: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


Test ride Can-Am Origin: la moto elettrica che fa dimenticare il motore a scoppio (ma occhio all'autonomia) Test ride Can-Am Origin: la moto elettrica che f...
Logitech G325, G305 e G316 X: il tris per chi non vuole rinunciare a nulla, spendendo poco Logitech G325, G305 e G316 X: il tris per chi no...
Recensione POCO F9 pro: potenza da vero top di gamma, display da 185 Hz e finalmente una fotocamera da prendere sul serio Recensione POCO F9 pro: potenza da vero top di g...
Tra audio e AI: la ricetta di Qualcomm per l'agentic AI Tra audio e AI: la ricetta di Qualcomm per l'age...
Qualcomm annuncia la nuova generazione di SoC Snapdragon 8 Elite Gen 6 Qualcomm annuncia la nuova generazione di SoC Sn...
Apple apre Music Hall, una sala concerto...
Adobe arriva su Gemini e Claude: nuove f...
Non solo Fideuram: quasi 2 milioni di it...
I lettori CD di fascia alta potrebbero s...
Tutto il meglio di Amazon weekend: 5 nov...
Proscenic P15+ a 113€ su Amazon: scopa e...
TP-Link Wi-Fi 6 a 59,99€ e Tenda 4G03 Pr...
Un quasi top di gamma a 461€: lo smartph...
Roborock Saros 20 Neo e Flow Complete: 3...
Mac mini si trasforma: chip a 2 nanometr...
Su Amazon c'è un super TV Samsung...
La Cina ha rilasciato un satellite dallo...
Il satellite LINK è rientrato nel...
L'ESA risponde alle critiche di Jared Is...
La NASA annuncia il nuovo telescopio spa...
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: 13:55.


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