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..