Leon_13 Δημοσ. 7 Δεκεμβρίου 2010 Δημοσ. 7 Δεκεμβρίου 2010 έχω γραψει αυτό το κομμάτι κώδικα αλλά κάπου κολάει. > #include <vector> ... ... class GeneralValues { protected: char *Name; int Id; int RentDuration; float Price; float Price1; public: GeneralValues(char *v1, int v2, int v3, float v4, float v5) { strcpy (Name,v1); Id = v2; RentDuration = v3; Price = v4; Price1 = v5; } }; class Dvd : public GeneralValues { protected: int TimeDuration; public: Dvd(char *t1,int t2,int t3,float t4,float t5,int t6) : GeneralValues(t1,t2,t3,t4,t5) { TimeDuration = t6; } }; .... .... vector <Dvd *> VectorDvd; .... .... void SetValues() { VectorDvd.push_back(new Dvd("Lord", 1, 3, 2.0, 1.0,150)); } ο compiler δεν χτυπάει αλλά όταν πάω να το τρέξω. http://a.yfrog.com/img257/1364/errorww.jpg
Επισκέπτης Δημοσ. 7 Δεκεμβρίου 2010 Δημοσ. 7 Δεκεμβρίου 2010 >strcpy (Name,v1); Απ'ότι φαίνεται από τον κώδικα που έχεις κάνει post, δεν κάνεις πουθενά allocate χώρο για το Name member με αποτέλεσμα η strcpy να προσπαθεί να κάνει copy σε random bytes και να crashάρει το πρόγραμμα. Πρίν από την strcpy πρόσθεσε το εξής: >Name = new char[strlen(v1)+1]; Επίσης καλο είναι να αλλάξεις τους constructors έτσι ώστε το πρώτο όρισμα αντί για char * να είναι const char * Ο παρακάτω κώδικας κάνει compile και τρέχει χωρίς προβλήματα: >#include <vector> #include <cstring> class GeneralValues { protected: char *Name; int Id; int RentDuration; float Price; float Price1; public: GeneralValues (const char *v1, int v2, int v3, float v4, float v5) { Name = new char[strlen (v1) + 1]; std::strcpy (Name, v1); Id = v2; RentDuration = v3; Price = v4; Price1 = v5; } }; class Dvd : public GeneralValues { protected: int TimeDuration; public: Dvd (const char *t1, int t2, int t3, float t4, float t5, int t6):GeneralValues (t1, t2, t3, t4, t5) { TimeDuration = t6; } }; int main () { std::vector <Dvd *> VectorDvd; VectorDvd.push_back (new Dvd ("Lord", 1, 3, 2.0, 1.0, 150)); }
Leon_13 Δημοσ. 7 Δεκεμβρίου 2010 Μέλος Δημοσ. 7 Δεκεμβρίου 2010 τώρα είναι οκ, σε ευχαριστώ πολύ για τον χρόνο σου. πάντως χωρίς την διόρθωση μου έτρεξε σε άλλον υπολογιστή. πια η διαφορά του char * με το const char * που μου πρότεινες;
Επισκέπτης Δημοσ. 7 Δεκεμβρίου 2010 Δημοσ. 7 Δεκεμβρίου 2010 πια η διαφορά του char * με το const char * που μου πρότεινες; Όταν ένας pointer (πχ. const char *) ή ένα reference (πχ. const char &) είναι const qualified δεν επιτρέπει ο compiler την τροποποίηση της μνήμης στην οποία δείχνει (εμφανίζοντας σφάλμα). Για παράδειγμα ο παρακάτω κώδικας πετάει σφάλμα: > void invalid(const char *); int main() { invalid("noway"); } void invalid(const char *s) { s[0] = '\0'; // ή *s = 0; } Εάν είχαμε παραλείψει το const στην παράμετρο της συνάρτησης invalid ο compiler δεν θα πετούσε σφάλμα (ίσως κάποιο warning) και όταν θα τρέχαμε το πρόγραμμα το πιθανότερο θα ήταν να crashάρει (Segmentation fault) διότι τα string literals ("noway" σε αυτήν την περίπτωση) τα δεσμεύει ο compiler σε μνήμη που δεν πρέπει να τροποποιηθεί. πάντως χωρίς την διόρθωση μου έτρεξε σε άλλον υπολογιστή. Σε αυτές τις περιπτώσεις λέμε ότι έχουμε undefined behavior, δηλαδή σε κάποιο μηχάνημα μπορεί να τρέξει κανονικά αλλά το πιθανότερο είναι να crashάρει. Το σίγουρο πάντως είναι ότι είναι τεράστιο λάθος η καταχώρηση δεδομένων σε τυχαίες θέσεις μνήμης και είναι πολύ συχνό λάθος που κάνουν οι νέοι προγραμματιστές. Τέλος στον κώδικα που έδωσα στο προηγούμενο reply μου έχω παραλείψει τις δηλώσεις του copy constructor, destructor καθώς και του assignment operator για να μην κάνω περίπλοκο τον κώδικα. Συνήθως όμως όταν γίνεται δυναμική δέσμευση μνήμης στον constructor μίας κλάσης θα πρέπει να υλοποιούνται με προσοχή τα member functions που ανέφερα. Ελπίζω να βοήθησα!
Evgenios1 Δημοσ. 7 Δεκεμβρίου 2010 Δημοσ. 7 Δεκεμβρίου 2010 BTW εφοσον χρησιμοποιεις vector, γιατι δεν χρισιμοποιεις και string αντι του cstring ( . Επισης, αλλαξε το vector <Dvd *> VectorDvd με vector <Dvd> VectorDvd για να μην εχεις αλλα "περιεργα" προβληματα, γιατι με τετοιον compiler.... σιγουρα θα εχεις.
jstark Δημοσ. 7 Δεκεμβρίου 2010 Δημοσ. 7 Δεκεμβρίου 2010 Δύο πραγματάκια, 1. Γιατί δε χρησιμοποιείς το std::string οπως λέει και ο Ευγένιος. 2. Από τη στιγμή που έχεις pointer se base class (Dvd*) κάνε και κανέναν destructor virtual, γιατί κάποια στιγμή θα την πατήσεις και θα ψάχνεσαι.
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.