Buongiorno a tutti.
Ragazzi ho fatto un programma dove utilizzo sia il polimorfismo che la derivazione multipla. Il programma svolge il suo compito ma non so perchè dopo l'esecuzione mostra i seguenti messaggi nel terminale scritti in rosso (programmo sotto Ubuntu con Eclipse):
Suppongo che dipenda da qualche problema con l'allocazione dinamica (leggo heap e stack) ma se cosi fosse il compilatore non mi direbbe nulla nel momento in cui "alloco male" un puntatore?codice:*** glibc detected *** /home/adrycast/workspace/animali_derivazione/Debug/animali_derivazione: free(): invalid pointer: 0xbfc5b604 *** ======= Backtrace: ========= /lib/libc.so.6(+0x6c501)[0x17c501] /lib/libc.so.6(+0x6dd70)[0x17dd70] /lib/libc.so.6(cfree+0x6d)[0x180e5d] /usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0x3a5441] /home/adrycast/workspace/animali_derivazione/Debug/animali_derivazione[0x8048f18] /home/adrycast/workspace/animali_derivazione/Debug/animali_derivazione[0x80494ef] /lib/libc.so.6(__libc_start_main+0xe7)[0x126ce7] /home/adrycast/workspace/animali_derivazione/Debug/animali_derivazione[0x8048881] ======= Memory map: ======== 00110000-00267000 r-xp 00000000 08:02 253474 /lib/libc-2.12.1.so 00267000-00269000 r--p 00157000 08:02 253474 /lib/libc-2.12.1.so 00269000-0026a000 rw-p 00159000 08:02 253474 /lib/libc-2.12.1.so 0026a000-0026d000 rw-p 00000000 00:00 0 002fb000-003da000 r-xp 00000000 08:02 656528 /usr/lib/libstdc++.so.6.0.14 003da000-003de000 r--p 000de000 08:02 656528 /usr/lib/libstdc++.so.6.0.14 003de000-003df000 rw-p 000e2000 08:02 656528 /usr/lib/libstdc++.so.6.0.14 003df000-003e6000 rw-p 00000000 00:00 0 005ee000-00612000 r-xp 00000000 08:02 253478 /lib/libm-2.12.1.so 00612000-00613000 r--p 00023000 08:02 253478 /lib/libm-2.12.1.so 00613000-00614000 rw-p 00024000 08:02 253478 /lib/libm-2.12.1.so 00ca6000-00cc2000 r-xp 00000000 08:02 253471 /lib/ld-2.12.1.so 00cc2000-00cc3000 r--p 0001b000 08:02 253471 /lib/ld-2.12.1.so 00cc3000-00cc4000 rw-p 0001c000 08:02 253471 /lib/ld-2.12.1.so 00eac000-00ec6000 r-xp 00000000 08:02 1316415 /lib/libgcc_s.so.1 00ec6000-00ec7000 r--p 00019000 08:02 1316415 /lib/libgcc_s.so.1 00ec7000-00ec8000 rw-p 0001a000 08:02 1316415 /lib/libgcc_s.so.1 00f1f000-00f20000 r-xp 00000000 00:00 0 [vdso] 08048000-0804b000 r-xp 00000000 08:02 1613514 /home/adrycast/workspace/animali_derivazione/Debug/animali_derivazione 0804b000-0804c000 r--p 00002000 08:02 1613514 /home/adrycast/workspace/animali_derivazione/Debug/animali_derivazione 0804c000-0804d000 rw-p 00003000 08:02 1613514 /home/adrycast/workspace/animali_derivazione/Debug/animali_derivazione 08bf2000-08c13000 rw-p 00000000 00:00 0 [heap] b7600000-b7621000 rw-p 00000000 00:00 0 b7621000-b7700000 ---p 00000000 00:00 0 b77f3000-b77f6000 rw-p 00000000 00:00 0 b780c000-b7810000 rw-p 00000000 00:00 0 bfc3b000-bfc5c000 rw-p 00000000 00:00 0 [stack]
Ovviamente non pretendo che vi mettiate a vedere tutto per filo e per segno ma magari siete già incappati in una situazione simile e potete indicarmi dove ho sbagliato.
UN GRAZIE ANTICIPATO A CHI RISPONDE![]()
PS
Qualcuno saprebbe spiegarmi anche come mai ogni volta che acquisisco una stringa utilizzando prima cin.ignore e poi cin.get finisce sempre per mangiarsi la prima lettera? Ad esempio inserisco PLUTO e lui legge LUTO...![]()
PPS
Non so se poi è utile, comunque allego anche l'output del programma e le varie sezioni di codice (non badate alla logica del programma, era solo per esercitarmi)
classe Animali (la classe base)
classe Cane (derivata di Animali)codice:/* * animali.h * * Created on: 16/feb/2011 * Author: adrycast */ #ifndef ANIMALI_H_ #define ANIMALI_H_ #include <iostream> #include <cstdlib> #include <cstring> using namespace std; typedef char * stringa; class Animali { stringa nome; float eta; public: //costruttori Animali(){nome=NULL;} Animali (const float & e) {eta=e;} Animali (const char N[]); Animali(const char N[], const float & e ); //funzioni polimorfe per le derivate virtual void verso (){} virtual void cibo(){} virtual void ChiSono() {} //funzioni per età void setEta(){cout << "\nInserire eta': "; cin >> eta;} float getEta() {return eta;} //funzioni per nome void setNome(){char n[15];cout<<"\nInserire nome: "; cin.ignore(); cin.get(n,14); nome=new char[strlen(n)+1]; strcpy(nome,n);} stringa getNome(){return nome;} //distruttore virtual ~Animali() {delete nome;} }; #endif /* ANIMALI_H_ */ /* * animali.cpp * * Created on: 16/feb/2011 * Author: adrycast */ #include "animali.h" Animali::Animali (const char N[]){ nome=new char[strlen(N)+1]; strcpy(nome,N); } Animali::Animali(const char N[], const float & e ){ nome=new char[strlen(N)+1]; strcpy(nome,N); eta=e; }
codice:/* * cane.h * * Created on: 16/feb/2011 * Author: adrycast */ #ifndef CANE_H_ #define CANE_H_ #include "animali.h" class Cane: public virtual Animali { stringa pelo; stringa razza; public: //Costruttori Cane (const char N[],const float & eta, const char P[], const char R[]); Cane (const char N[],const float & eta): Animali::Animali(N,eta) {} Cane (const char P[]): Animali::Animali() { pelo=new char [strlen(P)+1]; strcpy(pelo,P);} //ridefinizione delle funzioni virtuali virtual void verso() {cout << "\nBAU! BAU!";} virtual void cibo () {cout << "\nMangio di tutto!";} virtual void ChiSono() {cout << "\nSono un cane!";} //funzioni per pelo void setPelo() {char Pelo[10]; cout<< "\nPelo: "; cin.ignore(); cin.get(Pelo, 9); pelo= new char [strlen(Pelo)+1]; strcpy(pelo, Pelo);} stringa getPelo() {return pelo;} //funzioni per razza void setRazza(); stringa getRazza() {return razza;} //distruttore virtual ~Cane(){ delete pelo; delete razza;} }; #endif /* CANE_H_ */ /* * cane.cpp * * Created on: 16/feb/2011 * Author: adrycast */ #include "cane.h" Cane::Cane (const char N[],const float & eta, const char P[], const char R[]): Animali::Animali(N,eta) { razza= new char [strlen(R)+1]; strcpy(razza, R); pelo= new char [strlen(P)+1]; strcpy(pelo, P); } void Cane::setRazza(){ char R[15]; cout << "\nRazza:"; cin.ignore(); cin.get(R,14); razza= new char [strlen(R)+1]; strcpy(razza, R); }
classe Lupo (altra derivata da Animali)
codice:/* * lupo.h * * Created on: 16/feb/2011 * Author: adrycast */ #ifndef LUPO_H_ #define LUPO_H_ #include "animali.h" class Lupo: public virtual Animali { public: Lupo(const char N[], const float & e):Animali::Animali(N,e) {} virtual void verso() {cout << "\nGRR! GRR!";} virtual void cibo() {cout<<"\nPrediligo la carne fresca!";} virtual void ChiSono() {cout << "\nSono un lupo!";} virtual ~Lupo(){} }; #endif /* LUPO_H_ */
classe CaneLupo (derivata da Cane e Lupo)
MAINcodice:/* * canelupo.h * * Created on: 16/feb/2011 * Author: adrycast */ #ifndef CANELUPO_H_ #define CANELUPO_H_ #include "animali.h" #include "cane.h" #include "lupo.h" class CaneLupo: public Cane, public Lupo { public: CaneLupo (const char N[], const float & e): Cane::Cane(N,e), Lupo::Lupo(N,e){} virtual void verso() {Cane::verso(); Lupo::verso();} virtual void cibo() {Cane::cibo(); cout<<"\n ed inoltre"; Lupo::cibo();} virtual void ChiSono() {Cane::ChiSono(); cout << "\n ed inoltre"; Lupo::ChiSono();} virtual ~CaneLupo() {} }; #endif /* CANELUPO_H_ */
Qui poi chiamo o non chiamo i distruttori e dealloco o non dealloco i puntatori al prog non fa nessuna differenza, ho sempre l'output di errore dal terminale.codice:/* * main.cpp * * Created on: 16/feb/2011 * Author: adrycast */ #include "animali.h" #include "cane.h" #include "lupo.h" #include "canelupo.h" int main () { char N[20]; float e; //azioni preliminari (per i costruttori) cout << "\nNome animale: "; cin.ignore(); cin.get(N, 19); cout << "\Eta' animale: "; cin >> e; //inizializzo Classi Animali a(N,e); Cane c(N,e); Lupo l(N,e); CaneLupo cl(N,e); cout << "\n****INIZIO****\n"; cout << "\n**CHIAMATE NORMALI!"; //su Animali cout << "\neta' animale: "<<a.getEta(); cout << "\nnome animale: "<<a.getNome(); cout << "\n"; cout << "\nRICHIAMO CANE"; //su Cane c.ChiSono(); c.setPelo(); cout << "\nHai scritto che il mio pelo è "<<c.getPelo(); cout << "\n"; c.setRazza(); cout << "\nHai scritto che appartengo alla razza dei "<<c.getRazza(); cout << "\n"; cout << "\nIl mio verso è "; c.verso(); cout << " ed inolte "; c.cibo(); cout << "\n"; cout << "\nRICHIAMO LUPO"; //su Lupo l.ChiSono(); cout << "\n"; cout << "\nIl mio verso è "; l.verso(); cout << " ed inolte "; l.cibo(); cout << "\n"; cout << "\nRICHIAMO CANELUPO"; //su CaneLupo cl.ChiSono(); cout << "\n"; cout << "\nIl mio verso è "; cl.verso(); cout << " ed inolte "; cl.cibo(); cout << "\n****FINE PROG NORMALE****\n"; cout << "\n****INIZIO PROG CON PUNTATORI E BINDING DINAMICO****\n"; typedef Animali * A; cout << "\n**Punto CANE da ANIMALI**"; A ptrc=&c; ptrc->ChiSono(); cout << "\n"; ptrc->verso(); cout << "\n"; ptrc->cibo(); cout << "\n"; cout << "\n**Punto LUPO da ANIMALI**"; A ptrl=&l; ptrl->ChiSono(); cout << "\n"; ptrl->verso(); cout << "\n"; ptrl->cibo(); cout << "\n"; cout << "\n**Punto CANELUPO da CANE**"; typedef Cane * C; C ptrcl=&cl; ptrcl->ChiSono(); cout << "\n"; ptrcl->verso(); cout << "\n"; ptrcl->cibo(); cout << "\n"; delete ptrc; delete ptrl; delete ptrcl; a.~Animali(); c.~Cane(); l.~Lupo(); cl.~CaneLupo(); cout << "\n**********FINE**********\n"; return EXIT_SUCCESS; }
OUTPUT
Ovviamente seguito dall'errore scritto sopra.codice:Nome animale: PLUTO ta' animale: 8 ****INIZIO**** **CHIAMATE NORMALI! eta' animale: 8 nome animale: LUTO RICHIAMO CANE Sono un cane! Pelo: corto Hai scritto che il mio pelo è corto Razza:labrador Hai scritto che appartengo alla razza dei labrador Il mio verso è BAU! BAU! ed inolte Mangio di tutto! RICHIAMO LUPO Sono un lupo! Il mio verso è GRR! GRR! ed inolte Prediligo la carne fresca! RICHIAMO CANELUPO Sono un cane! ed inoltre Sono un lupo! Il mio verso è BAU! BAU! GRR! GRR! ed inolte Mangio di tutto! ed inoltre Prediligo la carne fresca! ****FINE PROG NORMALE**** ****INIZIO PROG CON PUNTATORI E BINDING DINAMICO**** **Punto CANE da ANIMALI** Sono un cane! BAU! BAU! Mangio di tutto! **Punto LUPO da ANIMALI** Sono un lupo! GRR! GRR! Prediligo la carne fresca! **Punto CANELUPO da CANE** Sono un cane! ed inoltre Sono un lupo! BAU! BAU! GRR! GRR! Mangio di tutto! ed inoltre Prediligo la carne fresca!


)
Rispondi quotando