|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Torino (provincia)
Messaggi: 960
|
[newbie] problema "liste" con il C.
salve a tutti! Sono un totale principiante che sta cercando di imparare il C per esigenze scolastiche.. ho un problema nella gestione delle liste dinamiche.
Ho definito una struttura in questo modo: struct elem { char Titolo[20]; char Autori[20]; struct elem *link_t; struct elem *link_a; }; il problema è che inizializzando un puntatore in questo modo *t2 = NULL si verifica questa situazione: t2->Titolo = NULL t2->Autori= "" così quando dopo controllo se t2 != NULL la risposta è positiva. Come posso fare?? grazie per l'aiuto!! allego il file sorgente completo e la finestra con l'errore p.s. il programmino dovrebbe collocare la struttura creata in ordine alfabetico rispetto alle altre... #include <stdio.h> #include <string.h> #include <stdlib.h> struct elem { char Titolo[20]; char Autori[20]; struct elem *link_t; struct elem *link_a; }; void ordina_autori (struct elem *aux, struct elem **testa ) { struct elem *t1 = NULL, *t2 = NULL; t1 = t2 = *testa; //Collega la struttura in base agli autori while (t2->Autori && strcmp(aux->Autori, t2->Autori) > 0 ) { t1 = t2; t2 = t1->link_a; } if (t1 == t2) { aux->link_a = *testa; *testa = aux; } else { t1->link_a = aux; aux->link_a = t2; } } main () { struct elem *testa_a = NULL, *testa_t = NULL, *nuova_t = NULL, *nuova_a = NULL; char istruzione[40]; int i; printf("\nInserire una scheda (EOF per finire) => "); for (i=0; i<5; i++) { gets(istruzione); nuova_t = nuova_a = (struct elem *) malloc (sizeof(struct elem)); sscanf(istruzione, "%s %s", nuova_t->Titolo, nuova_t->Autori); ordina_autori (nuova_a, &testa_a); printf("Inserire un altra scheda (EOF per finire) => "); } return 0; }
__________________
Nel mercatino ho concluso con: eleoluca, huangwei, jai, ^v3rsus, Rinos, arvey, kinderboy. |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Torino (provincia)
Messaggi: 960
|
errore
__________________
Nel mercatino ho concluso con: eleoluca, huangwei, jai, ^v3rsus, Rinos, arvey, kinderboy. |
|
|
|
|
|
#3 |
|
Moderatore
Iscritto dal: Nov 2003
Messaggi: 16213
|
Ciao.
Solo qualche nota qua e là, non ho letto il codice a fondo. Se esegui: Codice:
*t2=NULL; Il codice: Codice:
t2->Titolo=NULL; t2->Autori=""; Anzitutto, Titolo e Autori sono array e non puntatori, quindi non puoi inizializzarli, né a NULL, né a nessun altro valore. Inoltre, se pure Autori fosse un puntatore, la riga non lo inizializzerebbe a NULL, ma lo farebbe puntare all'inizio di una stringa vuota (che non è NULL, ma una stringa che contiene il solo null character). Inoltre, attenzione: quando esegui: Codice:
nuova_t = nuova_a = (struct elem *) malloc (sizeof(struct elem));
__________________
Ubuntu è un'antica parola africana che significa "non so configurare Debian" Scienza e tecnica: Matematica - Fisica - Chimica - Informatica - Software scientifico - Consulti medici REGOLAMENTO DarthMaul = Asus FX505 Ryzen 7 3700U 8GB GeForce GTX 1650 Win10 + Ubuntu |
|
|
|
|
|
#4 | ||
|
Senior Member
Iscritto dal: Apr 2001
Città: Torino (provincia)
Messaggi: 960
|
innanzitutto grazie per l'aiuto
Quote:
Quote:
Cmq ho focalizzato il problema che mi blocca tutto: non riesco a trovare un controllo che mi ritorni NULL quando t2->Autori punta ad una stringa vuota!! Ho provato con (t2->Autori[0] != '\0') e (strlen(t2->Autori)) ma in entrambi i casi il programma si blocca...
__________________
Nel mercatino ho concluso con: eleoluca, huangwei, jai, ^v3rsus, Rinos, arvey, kinderboy. |
||
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Torino (provincia)
Messaggi: 960
|
Processor Fault
sto incontrando altri problemi con il compilatore Tc++ 4.5
Allego un programmino elementare che però non gira!! se inizializzo un vettore di strutture di 3 elementi tutto ok, se gli elementi sono già 10 si pianta sembrerebbero problemi di memoria... sapreste dirmi come evitarli?? grazie
__________________
Nel mercatino ho concluso con: eleoluca, huangwei, jai, ^v3rsus, Rinos, arvey, kinderboy. |
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Oct 2002
Città: Roma
Messaggi: 1502
|
Nel primo for l'indice i lo fai andare da 1 a N_LIBRI il che è errato, in quanto gli array sono indicizzati a partire da zero, quindi i deve variare da zero fino a N_LIBRI - 1, come fai nel secondo for.
Ciao.
__________________
Sun Certified Java Programmer EUCIP Core Level Certified European Certification of Informatics Professionals |
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Torino (provincia)
Messaggi: 960
|
ops è vero...
cmq mettendo a posto quello il problema rimane! poi un'altra cosa... nei file exe generati da Tc pp101 (avrà 10 anni) cliccando con il destro su proprietà posso impostare il quantitativo di memoria da riservagli (è su auto e va bene infatti...). Al contrario con gli eseguibili generati da Tc++4.5 per win cliccando su proprietà appaiono solo 3 "linguetti" e posso solo cambiare autore, note etc.. niente riguardo la memoria!!! il risultato finale è che i file compilati dal primo funzionano sempre, quelli compilati dal secondo funzionano solo se il numero di variabili è ridotto.
__________________
Nel mercatino ho concluso con: eleoluca, huangwei, jai, ^v3rsus, Rinos, arvey, kinderboy. |
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Oct 2002
Città: Roma
Messaggi: 1502
|
Ma perkè non cambi compilatore? Non l'ho mai sentito questo...
__________________
Sun Certified Java Programmer EUCIP Core Level Certified European Certification of Informatics Professionals |
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Torino (provincia)
Messaggi: 960
|
boh a scuola è quello che va per la maggiore, pensavo fosse abbastanza conosciuto! Il nome completo è "Borland Turbo C++ 4.5 for win".
Cmq alla fine sono riusciuto a risolvere tutti i problemi, è bastato dichiarare il vettore di strutture come *record e allocargli la memoria necessaria solo in un secondo momento con la malloc!! Ora il prog è Rock Solid
__________________
Nel mercatino ho concluso con: eleoluca, huangwei, jai, ^v3rsus, Rinos, arvey, kinderboy. |
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Torino (provincia)
Messaggi: 960
|
rieccomi qui con il quesito del giorno... cosa c'è che non va in
if (aux = (Libro *) malloc (sizeof(Libro)) == NULL) { printf("Memoria insufficiente, impossibile inserire nuovo record.\n"); return -1; } qui il programma si pianta (Libro è una struttura rinominata con typedef)
__________________
Nel mercatino ho concluso con: eleoluca, huangwei, jai, ^v3rsus, Rinos, arvey, kinderboy. |
|
|
|
|
|
#11 | |
|
Moderatore
Iscritto dal: Nov 2003
Messaggi: 16213
|
Quote:
L'espressione: Codice:
aux = (Libro *) malloc (sizeof(Libro)) == NULL Codice:
(aux=(Libro*)malloc(sizeof(Libro))) == NULL Codice:
aux = ((Libro*)malloc(sizeof(Libro))==NULL) Siccome aux è un puntatore, qualunque cosa cerchi in seguito di usare il suo valore si ritrova o alla locazione zero, che non è utilizzabile, o alla locazione 1, che è occupata dal sistema (sei sotto DOS, se ho capito bene): un'operazione di scrittura su una di queste zone provoca un errore. [Modalità "io ciò Linux Solo che Linux ti fa uscire con un messaggio di errore, Microzozz si impianta. [Modalità "io ciò Linux Prova a correggere questa riga, e facci sapere che succede.
__________________
Ubuntu è un'antica parola africana che significa "non so configurare Debian" Scienza e tecnica: Matematica - Fisica - Chimica - Informatica - Software scientifico - Consulti medici REGOLAMENTO DarthMaul = Asus FX505 Ryzen 7 3700U 8GB GeForce GTX 1650 Win10 + Ubuntu |
|
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Oct 2002
Città: Roma
Messaggi: 1502
|
Purtroppo la sintassi del c ti permette di scrivere un sacco di cose, ma è anche piena di trappole e se non la si conosce a fondo si possono combinare dei casini, sopratutto se il programma non va in crash come nel tuo caso, per cui ti accorgi subito che c'è un bug.
Nel caso specifico almeno un errore è nella riga: if (aux = (Libro *) malloc (sizeof(Libro)) == NULL) perkè quello che tu vuoi fare è assegnare a aux l'indirizzo restituito dalla malloc e poi vedere se tale indirizzo è NULL, però, in virtù della precedenza degli operatori, viene eseguito prima il controllo sull'uguaglianza a NULL e poi l'assegnamento; se tu scrivi: int ok = 1 == 0; viene prima eseguito 1 == 0 producendo il risultato booleano che viene quindi assegnato alla variabile ok; analogamente con aux = (Libro *) malloc (sizeof(Libro)) == NULL viene eseguito prima (Libro *) malloc (sizeof(Libro)) == NULL che restituisce zero se l'indirizzo restituito dalla malloc non è NULL (come accade quasi sempre), o uno viceversa, e quindi assegni a aux rispettivamente zero o uno, ovvero hai un puntatore che punta a zero (NULL) o alla locazione 1, causando quindi il crash. Prova allora a mettere le parentesi if ((aux = (Libro *) malloc (sizeof(Libro)) )== NULL) o ancora meglio evita queste facilitazioni della sintassi, che secondo me complicano solo la vita perche rendono il codice poco leggibile e favoriscono i bug: aux = (Libro *) malloc (sizeof(Libro)); if(aux == NULL){ } non ti piace cosi?
__________________
Sun Certified Java Programmer EUCIP Core Level Certified European Certification of Informatics Professionals |
|
|
|
|
|
#13 | |
|
Senior Member
Iscritto dal: Oct 2002
Città: Roma
Messaggi: 1502
|
Quote:
Sempre a denigrare windows...windows non si pianta affatto, ti fà uscire la finestrella in cui ti dice che il programma ha causato un errore, clicchi sul pulsante 'chiudi', e continua normalmente, linux ti fa uscire il messagio 'segmentation fault' (credo) sulla console, non vedo la differenza
__________________
Sun Certified Java Programmer EUCIP Core Level Certified European Certification of Informatics Professionals |
|
|
|
|
|
|
#14 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Torino (provincia)
Messaggi: 960
|
che pollo che sono!!
avete ragione l'errore era proprio lì... probabilmente mi ha fregato il gran numero di parentesi aperte. grazie a tutti. p.s. la cosa veramente vergognosa è che per 4-5 volte ho ignorato il warning che invece mi segnalava il tentativo di conversione INT->PTR... devo iniziare a leggere quei messaggi!!
__________________
Nel mercatino ho concluso con: eleoluca, huangwei, jai, ^v3rsus, Rinos, arvey, kinderboy. Ultima modifica di Diabolik.cub : 25-05-2004 alle 02:26. |
|
|
|
|
|
#15 |
|
Senior Member
Iscritto dal: May 2002
Città: somewhere in Europe
Messaggi: 2554
|
Eh Diabolik...anche tu con Valenzano?
|
|
|
|
|
|
#16 | |
|
Senior Member
Iscritto dal: Apr 2001
Città: Torino (provincia)
Messaggi: 960
|
Quote:
incredibile adesso scopriamo che siamo compagni di corso!!! io sono 'inf' PRLP quindi al primo corso... (ovviamente primo anno) e tu?
__________________
Nel mercatino ho concluso con: eleoluca, huangwei, jai, ^v3rsus, Rinos, arvey, kinderboy. |
|
|
|
|
|
|
#17 |
|
Senior Member
Iscritto dal: May 2002
Città: somewhere in Europe
Messaggi: 2554
|
eh si...
sto forum è una figata cmq...e quella esercitazione è una bella rogna.. |
|
|
|
|
|
#18 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Torino (provincia)
Messaggi: 960
|
siamo agli sgoccioli!
ho praticamente ultimato il programmino che devo fare, e funziona tutto se non fosse per un piccolo problema legato alla funzione free per "disallocare" la memoria di strutture da eliminare.
Per lo scopo ho definito una funzione "libera_memoria (Libro **ptr_aux)" dove Libro è una struttura composta da 2 campi: una stringa e un puntatore alla struttura (per creare una lista dinamica). Il corpo della funzione è il seguente: { free (&(*ptr_aux)->Titolo); free (&(*aux)->link_t); } subito dopo averla eseguita nel main con Libro *aux; libera_memoria (&aux); libero il puntatore alla struttura con free (aux); Trovate qualche errore eclatante in queste righe di codice? Perchè dopo avermi liberato 5-6 puntatori mi viene il classico "Processor Fault" e non riesco a capire perchè! ciao e grazie.
__________________
Nel mercatino ho concluso con: eleoluca, huangwei, jai, ^v3rsus, Rinos, arvey, kinderboy. Ultima modifica di Diabolik.cub : 26-05-2004 alle 22:50. |
|
|
|
|
|
#19 |
|
Senior Member
Iscritto dal: Oct 2002
Città: Roma
Messaggi: 1502
|
Il campo titolo non è un puntatore a della memoria allocata dinamicamente, quindi non dovrebbe essere deallocato con free, almeno cosi penso, poi non capisco perche usi l'operatore & e perche passi un puntatore a puntatore come argomento della funzione. Io avrei fatto così:
Codice:
void libera_memoria (Libro *ptr_aux){
Libro * temp;
while(ptr_aux != NULL){
//mi mantengo il puntatore all'elemento successivo
temp = ptr_aux -> link_t;
free(ptr_aux);
ptr_aux = temp;
}
}
libera_memoria(aux); per liberare tutta la memoria allocata.
__________________
Sun Certified Java Programmer EUCIP Core Level Certified European Certification of Informatics Professionals Ultima modifica di anx721 : 26-05-2004 alle 23:09. |
|
|
|
|
|
#20 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Torino (provincia)
Messaggi: 960
|
dunque non ho capito...
la tua funzione se non sbaglio mi dealloca tutti i puntatori da quello che inserisci fino all'ultimo, giusto? io devo solo deallocare una singola struttura. Mettiamo che questa struttura *aux sia composta da 3 stringhe a un puntatore alla struttura, non devo deallocare manualmente questi 4 puntatori prima di deallocare il puntatore 'aux' alla struttura??
__________________
Nel mercatino ho concluso con: eleoluca, huangwei, jai, ^v3rsus, Rinos, arvey, kinderboy. |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 06:11.



















