Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Κάπου εδώ το είχα δει ότι μπορείς να τα βγάλεις όλα μα όλα και να είναι μόνο ο editor και το ελέγχεις όλο με shortcut(αν δεν κάνω λάθος ο groot το είχε γράψει σε κάποιο thread)

  • Απαντ. 38
  • Δημ.
  • Τελ. απάντηση

Συχνή συμμετοχή στο θέμα

Δημοσ.

Κάνω ένα theme να το βάλω GitHub, δεν μπορώ άλλο με την ασχήμια του. Σε functionality, ερωτεύσιμο. Έχει built-in bash, version control, gem management (Ruby), άπειρα χρήσιμο refactoring, απλά πύραυλος. Αλλά αν είναι να πονάνε τα μάτια μου, better no.

  • 2 εβδομάδες αργότερα...
Δημοσ.

Προσπαθώ να φτιάξω ένα custom vector με ελάχιστο functionality μιας και θα μου χρειαστεί το χειμώνα γιατί απαγορεύεται( :shifty: ) τουλάχιστον στις πρώτες ασκήσεις του μαθήματος(OOP) χρήση vector και γενικά STL.

 

Δουλεύει κανονικά για όσα δοκίμασα εκτός από string! Δοκίμασα δηλαδή στην αρχή να φτιάξω μια κλάση που έχει μόνο ένα string με ένα getter/setter αλλά έτρωγα segmentation στο reallocate όταν έκανα delete το αρχικό array. Δοκίμασα μετά ένα απλό string γιατί υπέθεσα οτί κάτι θα φταίει με την κλάση μιας και με άλλους standard types δούλευε κανονικά αλλά μάταια μιας και εκεί είχα το ίδιο πρόβλημα.

 

Έχει κανείς καμία ιδέα τι μπορεί να φταίει μιας και το Google δεν βοήθησε πολύ.

Link.png Site: Git

Δημοσ.

Προσπαθώ να φτιάξω ένα custom vector με ελάχιστο functionality μιας και θα μου χρειαστεί το χειμώνα γιατί απαγορεύεται( :shifty: ) τουλάχιστον στις πρώτες ασκήσεις του μαθήματος(OOP) χρήση vector και γενικά STL.

 

Δουλεύει κανονικά για όσα δοκίμασα εκτός από string! Δοκίμασα δηλαδή στην αρχή να φτιάξω μια κλάση που έχει μόνο ένα string με ένα getter/setter αλλά έτρωγα segmentation στο reallocate όταν έκανα delete το αρχικό array. Δοκίμασα μετά ένα απλό string γιατί υπέθεσα οτί κάτι θα φταίει με την κλάση μιας και με άλλους standard types δούλευε κανονικά αλλά μάταια μιας και εκεί είχα το ίδιο πρόβλημα.

 

Έχει κανείς καμία ιδέα τι μπορεί να φταίει μιας και το Google δεν βοήθησε πολύ.

Link.png Site: Git

 

Με ένα πρόχειρο κοίταγμα, στην realloc κάνεις

    void myrealloc() {
        T *newVec = new T[Vcapacity << 1];
        //        for (int i=0;i<this->size();i++)
        //            newVec[i] = items[i];
        memcpy(newVec, items, Vsize * sizeof(T));
        delete[] items;
        items = newVec;
        Vcapacity <<= 1;
    }

Που σημαίνει οτι:

 

Αντιγράφει δυαδικά όλα τα δεδομένα του προηγούμενου array στο επόμενο και μετά κάνει delete[] στο προηγούμενο array.

Που σημαίνει κάνει σε όλα τα στοιχεία του array ένα προς ένα.

 

Τι γίνεται όμως. Τα αντικείμενα στη c++ δεν αντιγράφονται με memcpy.

 

Η μάλλον η memcpy δεν κάνει αυτό που υποθέτεις οτι κάνει στην περίπτωση που έχει αντικείμενα όπως το string.

 

 

Γενικά. Όχι memcpy και αντικείμενα. 

 

Ας πάρουμε ως παράδειγμα το ίδιο το αντικείμενο σου που έφτιαξες και ας το απλοποιήσουμε λιγο:

template<class T>
class myVector {
public:
    myVector() {
        items = new T[16];
    }
    ~myVector(){
        delete[] items;
    }
private:
    T *items;
};

Και μετά εγώ σου δίνω αυτό:

myVector<int> *proto;
proto = new myVector<int>();
/*...fill proto with data...*/

myVector<int> *deftero;
deftero = new myVector<int>()

memcpy(deftero, proto, sizeof(myVector<int>));

delete proto;

Μετά απο τον κώδικα αυτό. Τι γίνεται με το δεύτερο αντικείμενο;

Ο δείκτης που έχει (items) που δείχνει; Τι έχει γίνει εκεί που δείχνει;

  • Like 1
Δημοσ.

Προσπαθώ να φτιάξω ένα custom vector με ελάχιστο functionality μιας και θα μου χρειαστεί το χειμώνα γιατί απαγορεύεται( :shifty: ) τουλάχιστον στις πρώτες ασκήσεις του μαθήματος(OOP) χρήση vector και γενικά STL.

 

Δουλεύει κανονικά για όσα δοκίμασα εκτός από string! Δοκίμασα δηλαδή στην αρχή να φτιάξω μια κλάση που έχει μόνο ένα string με ένα getter/setter αλλά έτρωγα segmentation στο reallocate όταν έκανα delete το αρχικό array. Δοκίμασα μετά ένα απλό string γιατί υπέθεσα οτί κάτι θα φταίει με την κλάση μιας και με άλλους standard types δούλευε κανονικά αλλά μάταια μιας και εκεί είχα το ίδιο πρόβλημα.

 

Έχει κανείς καμία ιδέα τι μπορεί να φταίει μιας και το Google δεν βοήθησε πολύ.

Link.png Site: Git

 

 

Για να καταλάβεις τι γίνεται μετατρεψε το τυπο του Course::name απo string σε int και σκεψου γιατι ο κωδικας σου συμπεριφεται έτσι..

 

Δωκιμασε να αλλαξεις το memalloc σε αυτο (χρειαζεσαι επισης το header algorithm)

std::copy_n(items, Vsize, newVec);
Δημοσ.

Με ένα πρόχειρο κοίταγμα, στην realloc κάνεις

    void myrealloc() {
        T *newVec = new T[Vcapacity << 1];
        //        for (int i=0;i<this->size();i++)
        //            newVec[i] = items[i];
        memcpy(newVec, items, Vsize * sizeof(T));
        delete[] items;
        items = newVec;
        Vcapacity <<= 1;
    }
Που σημαίνει οτι:

 

Αντιγράφει δυαδικά όλα τα δεδομένα του προηγούμενου array στο επόμενο και μετά κάνει delete[] στο προηγούμενο array.

Που σημαίνει κάνει σε όλα τα στοιχεία του array ένα προς ένα.

 

Τι γίνεται όμως. Τα αντικείμενα στη c++ δεν αντιγράφονται με memcpy.

 

Η μάλλον η memcpy δεν κάνει αυτό που υποθέτεις οτι κάνει στην περίπτωση που έχει αντικείμενα όπως το string.

 

 

Γενικά. Όχι memcpy και αντικείμενα. 

 

Ας πάρουμε ως παράδειγμα το ίδιο το αντικείμενο σου που έφτιαξες και ας το απλοποιήσουμε λιγο:

template<class T>
class myVector {
public:
    myVector() {
        items = new T[16];
    }
    ~myVector(){
        delete[] items;
    }
private:
    T *items;
};
Και μετά εγώ σου δίνω αυτό:

myVector<int> *proto;
proto = new myVector<int>();
/*...fill proto with data...*/

myVector<int> *deftero;
deftero = new myVector<int>()

memcpy(deftero, proto, sizeof(myVector<int>));

delete proto;

Μετά απο τον κώδικα αυτό. Τι γίνεται με το δεύτερο αντικείμενο;

Ο δείκτης που έχει (items) που δείχνει; Τι έχει γίνει εκεί που δείχνει;

 

Αυτό που περίμενα εγώ να γίνει είναι να μην υπάρχει κανένα πρόβλημα και να δείχνει στο πρώτο στοιχείο του items που έχει αντιγράψει.

 

Πήρα ως βάση αυτό:Link.png Site:

 

Που λέει μεταξύ άλλων:The underlying type of the objects pointed to by both the source and destination pointers are irrelevant for this function; The result is a binary copy of the data.

 

Μου τα ξέσκισε όλα το edit.

@DeltaLover Θα χρησιμοποιούσα αυτήν την συνάρτηση εξαρχής αλλά ο σκοπός είναι να μην χρησιμοποιήσω καθόλου stl για αυτό τον τύπο.

  • Like 1
Δημοσ.

Αυτό που περίμενα εγώ να γίνει είναι να μην υπάρχει κανένα πρόβλημα και να δείχνει στο πρώτο στοιχείο του items που έχει αντιγράψει.

 

Χμ. Δεν είναι ακριβώς έτσι τα πράγματα.

 

Διάβασε λίγο pointers. Τι είναι και τι κάνουν. 

 

π.χ. εδώ: 

http://www.tutorialspoint.com/cplusplus/cpp_pointers.htm

Δημοσ.

Χμ. Δεν είναι ακριβώς έτσι τα πράγματα.

 

Διάβασε λίγο pointers. Τι είναι και τι κάνουν. 

 

π.χ. εδώ: 

http://www.tutorialspoint.com/cplusplus/cpp_pointers.htm

Pointers γνωρίζω τουλάχιστον στο επίπεδο που μπορώ να γνωρίζω.

Το θέμα είναι τι συμβαίνει με την memcpy. Αφήνει τον pointer να δείχνει στο σημείο που έδειχνε ο pointer του proto?

Υπέθεσα οτί αλλάζει την διεύθυνση στο καινούριο items.

 

 

@DeltaLover Ο εύκολος τρόπος είναι αυτός αλλά είναι και αργός και  είπα μήπως μάθω και κάτι παραπάνω :-)

Δημοσ.

Pointers γνωρίζω τουλάχιστον στο επίπεδο που μπορώ να γνωρίζω.

Το θέμα είναι τι συμβαίνει με την memcpy. Αφήνει τον pointer να δείχνει στο σημείο που έδειχνε ο pointer του proto?

Υπέθεσα οτί αλλάζει την διεύθυνση στο καινούριο items.

 

 

Ακριβώς μετά το memcpy και τα δύο instances θα έχουν έναν pointer (ως περιεχόμενο. Το items δηλαδή) που θα εμπεριέχει την ίδια διεύθυνση μνήμης.

 

Αρα και οι 2 items θα δείχνουν στο ίδιο σημείο. Πρόσεξε. Στο ίδιο.

 

Και μετά κάνεις delete το proto. Τι γίνεται;

Δημοσ.

Ακριβώς μετά το memcpy και τα δύο instances θα έχουν έναν pointer που θα εμπεριέχει την ίδια διεύθυνση μνήμης.

 

Αρα και οι 2 θα δείχνουν στο ίδιο σημείο. Πρόσεξε. Στο ίδιο.

 

Και μετά κάνεις delete το proto. Τι γίνεται;

Έχει γίνει delete η διεύθυνση που δείχνει οπότε οπότε ξαναχρειαστεί δείχνει σε σκουπίδια.

 

Άρα άμα γράψω αυτό θα είμαι εντάξει:

myVector<int> *proto;
proto = new myVector<int>();
/*...fill proto with data...*/

myVector<int> *deftero;
deftero = new myVector<int>()

memcpy(deftero, proto, sizeof(myVector<int>));
myVector<int> *temp;
temp = proto;
proto = deftero;
delete temp;
Δημοσ.

 

Έχει γίνει delete η διεύθυνση που δείχνει οπότε οπότε ξαναχρειαστεί δείχνει σε σκουπίδια.

 

Άρα άμα γράψω αυτό θα είμαι εντάξει:

 

Ξαναδιάβασε γιατι έκανα update. 

 

Μη σκέφτεσαι τον pointer του proto ή του deftero.

 

Τον pointer items του κάθε instance. 

Δημοσ.

Ξαναδιάβασε γιατι έκανα update. 

 

Μη σκέφτεσαι τον pointer του proto ή του deftero.

 

Τον pointer items του κάθε instance. 

Κάθε item δείχνει στην προηγούμενη θέση του την οποία κάνω delete? και μετά όταν κανω delete καλείται ο destructor απο δυο διαφορετικά σημεία και γίνεται ....?

Δημοσ.

Pointers γνωρίζω τουλάχιστον στο επίπεδο που μπορώ να γνωρίζω.

Το θέμα είναι τι συμβαίνει με την memcpy. Αφήνει τον pointer να δείχνει στο σημείο που έδειχνε ο pointer του proto?

Υπέθεσα οτί αλλάζει την διεύθυνση στο καινούριο items.

 

 

@DeltaLover Ο εύκολος τρόπος είναι αυτός αλλά είναι και αργός και  είπα μήπως μάθω και κάτι παραπάνω :-)

 

Μερικα code review comments:

 

- Στο push_back περνας by value αντι γι αυτο περνα by reference.

 

- Αν σε απασχολει η ταχυτητα του κωδικα σου, τοτε μπορεις αντι για List<object> να βαλεις List<object*>.  Τι επιπλοκες εχεις αυτο?

 

-Hint: Μαθε τι ειναι το placement new  που μπορει να σου χρησιμεύση

 

- Declare == as friend (not as member)

 

- Χρησιμοποιησε const οπου ειναι δυνατον: πχ

 

      int size() { return Vsize; } καντο:

      int size() const { return Vsize; }

 

-O assignment operator σου πρεπει να τσεκαρει για ταυτοσημια

 

- Ποιος ο λογος που ο destructor σου δεν ειναι virtual? Γιατι το κανει αυτο το STL, τι επιπλοκες εχεις με αυτο? Πως λυνονται?

 

- Ο κωδικας σου δεν ειναι exception safe. Πως θα το διορθωσεις?  Που μπορουν να υπαρξουν leaks?

 

-  Πως δουλεύει ο Copy Constructor σου?  πχ   myVector<Course> Courses3(Courses);  Υπαρχει καποιο προβλημα?

  • Like 1
Δημοσ.

Μερικα code review comments:

 

- Στο push_back περνας by value αντι γι αυτο περνα by reference.

 

- Αν σε απασχολει η ταχυτητα του κωδικα σου, τοτε μπορεις αντι για List<object> να βαλεις List<object*>.  Τι επιπλοκες εχεις αυτο?

 

-Hint: Μαθε τι ειναι το placement new  που μπορει να σου χρησιμεύση

 

- Declare == as friend (not as member)

 

- Χρησιμοποιησε const οπου ειναι δυνατον: πχ

 

      int size() { return Vsize; } καντο:

      int size() const { return Vsize; }

 

-O assignment operator σου πρεπει να τσεκαρει για ταυτοσημια

 

- Ποιος ο λογος που ο destructor σου δεν ειναι virtual? Γιατι το κανει αυτο το STL, τι επιπλοκες εχεις με αυτο? Πως λυνονται?

 

- Ο κωδικας σου δεν ειναι exception safe. Πως θα το διορθωσεις?  Που μπορουν να υπαρξουν leaks?

 

-  Πως δουλεύει ο Copy Constructor σου?  πχ   myVector<Course> Courses3(Courses);  Υπαρχει καποιο προβλημα?

Ευχαριστώ για τις παρατηρήσεις και θα προσπαθήσω να τις διορθώσω όλες σιγά σιγά.

-Το push_back το έφτιαξα αλλά δεν ήταν στο commit στο github.

-Θα το κοιτάξω και θα επανέρθω.

-Το placement new δεν το ειχα ξανακούσει και λίγο που διάβασα στο so μου φάνηκε πολλά υπόσχομενο και θα το κοιτάξω.

-Για αυτό με το const έχεις δίκιο και θα διορθωθεί.

-Τον διόρθωσα.

-Δεν τον έκανα virtual γιατί δεν έχει derived classes.

-Σίγουρα έχει ένα leak στο [] operator το οποίο το γνωρίζω και δεν έχω ασχοληθεί ακόμα.

-Δεν έχω φτιάξει copy constructor ακόμα.

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα

  • Δημιουργία νέου...