Problema con funzione inserimento[c++]
Ragazzi ho un problema con la compilazione,credo sia la funzione inserimento perché é l'ultima che scritto,anche se l'ho controllata..
e file.h
grazie ciao..
#include "g.h" G::G(){testa=NULL;} G::~G(){elem*q; for(q=testa;q!=NULL;q=q->pun){testa=testa->pun; delete q; delete[] q->codice; q=testa;} } void G::inserisci(const char* mat,int esami){ elem*q,*k; for(q=testa;(q!=NULL)&&(q->esami<esami);q=q->pun){k=q;} elem* r=new elem; r->codice=new char[strlen(mat)+1]; strcpy(r->codice,mat); r->esami=esami; if(testa==NULL){ testa=r; r->pun=NULL; } else{ k->pun=r; r->pun=q;} } ostream& operator<<(ostream& os, const G& g){ elem*p; os<<"Matr"<<'\t'<<"Esami"<<'\t'<<endl; for (p=g.testa;p!=0;p=p->pun) os<<p->codice<<'\t'<<p->esami<<endl; return os; }
e file.h
#include<iostream> using namespace std; struct elem{ char* codice; int esami; elem* pun;}; class G{ private: elem* testa; public: G(); G(const G&); ~G(); void inserisci(const char*,int); friend ostream& operator<<(ostream&,const G&); };
grazie ciao..

Risposte
Ma quali errori ti da il compilatore?
mi crasha..
Posto anche il main
provo a spiegarmi meglio,quando compilo non crasha,nessun problema fino a quando premo enter per uscire dalla finestra dos ,crasha..
Posto anche il main
#include "g.h" int main(){ G z; cout<<z<<endl; z.inserisci("vvgvg",7); cout<<z<<endl; system("pause"); return 0; }
provo a spiegarmi meglio,quando compilo non crasha,nessun problema fino a quando premo enter per uscire dalla finestra dos ,crasha..
trovato niente??

Il tuo distruttore cancella (delete) 'q', e DOPO cancella 'q->codice'.
scusami ma é già cosi...
Comunque anche provando ad invertire non ottengo nulla...
comunque l'errore l'ho trovato adesso era si nel distruttore,ma nell'assegnazione di testa a q...
A questo punto ti chiedo,dov'è il problema di riassegnare q??
Per quanto riguarda il codice
ho sempre visto fare cosi,ma non riesco a capire cosa fanno le due istruzioni??
Non sarebbe meglio il contrario??
Comunque anche provando ad invertire non ottengo nulla...
G::~G(){elem*q; for(q=testa;q!=NULL;q=q->pun){testa=testa->pun; delete q; delete[] q->codice; q=testa;} }
comunque l'errore l'ho trovato adesso era si nel distruttore,ma nell'assegnazione di testa a q...
A questo punto ti chiedo,dov'è il problema di riassegnare q??
Per quanto riguarda il codice
delete q; delete[] q->codice;
ho sempre visto fare cosi,ma non riesco a capire cosa fanno le due istruzioni??
Non sarebbe meglio il contrario??

Non ho capito che avresti invertito... 
Comunque è quello che intendevo: se cancelli 'qualcosa' e poi cancelli 'qualcosa->altro', come può funzionare? Che oggetto sarebbe 'qualcosa->altro' se 'qualcosa' è cancellato?

Comunque è quello che intendevo: se cancelli 'qualcosa' e poi cancelli 'qualcosa->altro', come può funzionare? Che oggetto sarebbe 'qualcosa->altro' se 'qualcosa' è cancellato?
mentre scivevi ho modifiato il post sopra
Inndevo dire invertiro in questo modo
Sono d'accordo con te ,ma la cancellazione di qualcosa non é
"Rggb":
Non ho capito che avresti invertito...![]()
Inndevo dire invertiro in questo modo
delete[]q->codice; delete q;
"Rggb":
Comunque è quello che intendevo: se cancelli 'qualcosa' e poi cancelli 'qualcosa->altro', come può funzionare? Che oggetto sarebbe 'qualcosa->altro' se 'qualcosa' è cancellato?
Sono d'accordo con te ,ma la cancellazione di qualcosa non é
delete q ??,cioé il puntatore alla struttura...
C'è anche un altro problema, la riassegnazione 'q=q->pun' a fine ciclo... quale sarebbe il codice del distruttore adesso? Funziona?
si ho aggiustato funziona tutto perfettamente,ma non riesco a rispondere da solo a alle due domande che ho fatto prima..
Sai dirmi perché era quello il problema??

Allora, siccome ho un po' perso il filo e non ho ancora capito cosa hai modificato e come, torno al codice che hai postato la prima volta:
Ci vedo due problemi:
1) ad ogni ciclo, alla fine c'è l'assegnazione q=q->pun, quindi lo assegni due volte; infatti il codice del ciclo for è equivalente a questo:
2) cancella q->codice dopo aver cancellato q, che potrebbe portare a risultati non previsti: dopo aver eseguito una delete, un oggetto non è qualcosa di referenzialmente valido.
Ed ora parliamo delle modifiche che hai fatto: puoi postare il codice? Cioé, hai tolto l'assegnazione doppia, hai spostato le righe, cos'altro? Non l'ho capito ancora...
G::~G(){elem*q; for(q=testa;q!=NULL;q=q->pun){testa=testa->pun; delete q; delete[] q->codice; q=testa;} }
Ci vedo due problemi:
1) ad ogni ciclo, alla fine c'è l'assegnazione q=q->pun, quindi lo assegni due volte; infatti il codice del ciclo for è equivalente a questo:
q=testa; while (q != NULL) { testa=testa->pun; delete q; delete[] q->codice; q=testa; q=q->pun; }
2) cancella q->codice dopo aver cancellato q, che potrebbe portare a risultati non previsti: dopo aver eseguito una delete, un oggetto non è qualcosa di referenzialmente valido.
Ed ora parliamo delle modifiche che hai fatto: puoi postare il codice? Cioé, hai tolto l'assegnazione doppia, hai spostato le righe, cos'altro? Non l'ho capito ancora...

questo é il codice
Per il resto continuo a pensare ,che il queste due righe sia meglio scriverle cosi,credo che sia meglio deletare prima il qualcosa->altro e poi il qualcosa...
Potresti spiegarmelo??
ps:comunque adesso funziona tutto..
#include "g.h" G::G(){testa=NULL;} G::~G(){elem*q; for(q=testa;q!=NULL;q=q->pun){testa=testa->pun; delete q; delete[]q->codice; /*qui avevo inserito un q=testa; che mi dava problemi,ma non sono sicuro di aver capito il motivo..*/ } } void G::inserisci(const char* mat,int esami){ elem*q,*k; for(q=testa;(q!=NULL)&&((q->esami)<esami);q=q->pun){k=q;} elem* r=new elem; r->codice=new char[strlen(mat)+1]; strcpy(r->codice,mat); r->esami=esami; if(testa==NULL){ testa=r; r->pun=NULL; } else{ k->pun=r; r->pun=q;} } G::G(const char* nome){ char codice[15]; int esami; fstream ff; ff.open(nome,ios::in); if(!ff) { cerr<<"File non trovato"<<endl; exit(1); } while(ff>>codice){ ff>>esami; inserisci(codice,esami);} } bool G::verifica(const char* c,int n){ elem*q; for(q=testa;q!=NULL;q=q->pun)if(strcmp(q->codice,c)==0){q->esami=n;return true;} return false; } G::G(const G& g){ elem*q,*s,*k; testa=NULL; for(q=g.testa;q!=NULL;q=q->pun){ for(s=testa;s!=NULL;s=s->pun){k=s;} elem*r=new elem; r->codice=new char[strlen(q->codice)+1]; strcpy(r->codice,q->codice); r->esami=q->esami; if(testa==NULL){testa=r; r->pun=NULL;} else{ k->pun=r; r->pun=s;} } } ostream& operator<<(ostream& os, const G& g){ elem*p; os<<"Matr"<<'\t'<<"Esami"<<'\t'<<endl; for (p=g.testa;p!=0;p=p->pun) os<<p->codice<<'\t'<<p->esami<<endl; return os; }
Per il resto continuo a pensare ,che il queste due righe sia meglio scriverle cosi,credo che sia meglio deletare prima il qualcosa->altro e poi il qualcosa...
Potresti spiegarmelo??
delete[] q->codice; delete q;
ps:comunque adesso funziona tutto..
L'errore originale era quasi sicuramente dovuto alla doppia assegnazione di 'q'; alla fine del ciclo c'era un 'q=testa', nel momento in cui questo era l'ultimo elemento esso era NULL, quindi 'q' valeva NULL, ma successivamente (ultima istruzione del ciclo) veniva assegnato 'q=q->pun', e q->pun non esistendo generava una violazione di accesso.
Adesso funziona? Beh, anche se non cancelli tutto, comunque il distruttore lo richiami solo prima di uscire dal programma, e quindi la memoria allocata viene comunque rilasciata al sistema.
Giustamente.
Adesso funziona? Beh, anche se non cancelli tutto, comunque il distruttore lo richiami solo prima di uscire dal programma, e quindi la memoria allocata viene comunque rilasciata al sistema.
"Gianni91":
Per il resto continuo a pensare ,che il queste due righe sia meglio scriverle cosi,credo che sia meglio deletare prima il qualcosa->altro e poi il qualcosa...
Giustamente.
Ok ,adesso ci sono, grazie per il tuo aiuto..
