bnvdarklord Δημοσ. 27 Ιουνίου 2012 Δημοσ. 27 Ιουνίου 2012 Φτιάχνω ενα προγραμματάκι σε C++ που θα παράγει τυχαίους λαβυρίνθους. Ποτέ δεν εχω φτιάξει κάτι "σοβαρό" σε C++, και έτσι είπα να το κανω εκεί αντι να βασιστώ στις ευκολίες των C# και Java κτλ. Ενώ όλα πήγαιναν καλά παρουσιάστηκε το εξής πρόβλημα, το οποίο δεν έχει καν λογική (προς το παρον) Σε κάποιο σημείο λοιπόν στην κλάση Maze έχω την εξής μέθοδο: > bool Maze::checkValidPos(int x, int y, int from, char* color) { bool invalid = false; if(from != UP) invalid = invalid || maze->isColor(x, y+1, color); if(from != DOWN) invalid = invalid || maze->isColor(x, y-1, color); if(from != RIGHT) invalid = invalid || maze->isColor(x-1, y, color); if(from != LEFT) invalid = invalid || maze->isColor(x+1, y, color); //std::cout << invalid << std::endl; return invalid; } Ουσιαστικά ελέγχει αν ειναι valid η επόμενη κινηση για τον path generator. Όπως είναι με το comment στο cout, δεν δημιουργείται το path στην εικόνα που αποθηκεύω.(μια γραμμή ουσιαστικά που στρίβει τυχαία) Αν κανω uncomment το cout, δημιουργείται ένα path στην εικόνα που αποθηκεύω. Πώς γινεται αυτό; Παραθέτω και μία εικόνα, σε περίπτωση που δεν εγινα κατανοητός.
Moderators Praetorian Δημοσ. 27 Ιουνίου 2012 Moderators Δημοσ. 27 Ιουνίου 2012 Πολύ περίεργο αυτό. Κατά τη γνώμη μου δεν ευθύνεται ο αποσχολιασμός του cout που δε γράφει (ή δεν δημιουργείται path ) στην εικόνα. 1. Νομίζω ότι κάτι πάει στραβά με τα conditions που έχεις (βασικά η λογική τους μου φαίνεται αχρείαστα σύνθετη και επίσης κάπου κάτι είναι ανεστραμμένο είτε στους ελέγχους UP / DOWN είτε στο LEFT / RIGHT. 2. Πώς γράφεις στην εικόνα; Φροντίζεις να κλείσεις το αρχείο έπειτα;
bnvdarklord Δημοσ. 27 Ιουνίου 2012 Μέλος Δημοσ. 27 Ιουνίου 2012 Τα conditions αυτά απλά κοιτάνε τα 4 blocks γυρω από το x,y σημείο να μην εχουν τοίχο. Τα ifs υπάρχουν για να μην ελέγχξει το σημείο απο το οποίο ήρθε(για αυτο ειναι αναποδα). Ουσιαστικά δεν θελω να ακουμπάνε καν δυο paths μεταξυ τους για αυτο ειναι τέτοιος ο έλεγχος. Το αρχείο το κλείνω κανονικά με close. edit: Επισυνάπτω τον κώδικα σε περίπτωση που δεν βαριεται να το κοιτάξει κανεις. MazeGen.zip
Moderators Praetorian Δημοσ. 27 Ιουνίου 2012 Moderators Δημοσ. 27 Ιουνίου 2012 > if(from != UP) invalid = invalid || maze->isColor(x, y+1, color); Πχ εδώ καταλαβαίνω ότι λες: Αν ΔΕΝ κινείται προς το (x, y) προερχόμενος από ΠΑΝΩ, τοτε το (x,y) δεν είναι έγκυρη κίνηση αν ο λαβύρινθος έχει ήδη σημείο (τοίχο; ) στο (x, y+1) (σημείο ΠΑΝΩ από το (x, y)). Ok. > if(from != RIGHT) invalid = invalid || maze->isColor(x-1, y, color); Εδώ πάλι λες : Αν ΔΕΝ κινείται προς το (x, y) προερχόμενος από ΔΕΞΙΑ, τοτε το (x,y) δεν είναι έγκυρη κίνηση αν ο λαβύρινθος έχει ήδη σημείο στο (x-1, y) (σημείο ΑΡΙΣΤΕΡΑ από το (x, y)). Αυτό εννοούσα ότι κάπου κάτι μου φαίνεται ανεστραμμένο. Edit: o κώδικάς σου, σε εμένα (linux) δημιουργεί bitmap (όπως το έχεις με το cout αποσχολιασμένο) κανονικά ή πετάει segmentation fault.
bnvdarklord Δημοσ. 27 Ιουνίου 2012 Μέλος Δημοσ. 27 Ιουνίου 2012 Δημιουργεί bitmap ανεξάρτητα cout; Το segmentation fault το ξερω, αλλα εχω σκαλώσει τώρα με αυτό και δεν το χω ψαξει. Ειναι σχετικά σπάνιο αν δεν κανω λαθος.
Moderators Praetorian Δημοσ. 27 Ιουνίου 2012 Moderators Δημοσ. 27 Ιουνίου 2012 Ναι. Πέρα από τις φορές που πετάει το seg fault, το bmp δημιουργείται. (πχ στις 13 εκτελέσεις, οι3 ήταν seg fault). Οι υπόλοιπες έδωσαν τα bmp του attachment: tmpMaze.zip
Directx Δημοσ. 27 Ιουνίου 2012 Δημοσ. 27 Ιουνίου 2012 Δημιουργεί bitmap ανεξάρτητα cout; Το segmentation fault το ξερω, αλλα εχω σκαλώσει τώρα με αυτό και δεν το χω ψαξει. Ειναι σχετικά σπάνιο αν δεν κανω λαθος. Πριν μερικούς μήνες είχα ακούσει ένα παρόμοιο παράξενο πρόβλημα, η αιτία τελικά αποδείχθηκε σε ένα σφάλμα δέσμευσης μνήμης σε ένα τμήμα του λογισμικού το οποίο τελικά είχε σαν αποτέλεσμα μια αναπάντεχη (αδύνατη) δυσλειτουργία σε ένα άλλο σημείο του. Συνεπώς αν κάνεις πολλές δεσμεύσεις μνήμης κλπ ψάξε με προσοχή τον κώδικα σου για array overflows κλπ. Καλή τύχη!
bnvdarklord Δημοσ. 27 Ιουνίου 2012 Μέλος Δημοσ. 27 Ιουνίου 2012 Ναι. Πέρα από τις φορές που πετάει το seg fault, το bmp δημιουργείται. (πχ στις 13 εκτελέσεις, οι3 ήταν seg fault). Οι υπόλοιπες έδωσαν τα bmp του attachment: Δοκίμασα επίσης με g++ από cmd αντί του codeblocks μπας και, αλλα τίποτα. Αρα παιζει σε linux και οχι σε windows.. Ενδιαφέρον. Πριν μερικούς μήνες είχα ακούσει ένα παρόμοιο παράξενο πρόβλημα, η αιτία τελικά αποδείχθηκε σε ένα σφάλμα δέσμευσης μνήμης σε ένα τμήμα του λογισμικού το οποίο τελικά είχε σαν αποτέλεσμα μια αναπάντεχη (αδύνατη) δυσλειτουργία σε ένα άλλο σημείο του. Συνεπώς αν κάνεις πολλές δεσμεύσεις μνήμης κλπ ψάξε με προσοχή τον κώδικα σου για array overflows κλπ. Καλή τύχη! --EDIT Ο κώδικας σου χτυπάει στην ρουτίνα Bitmap::Add κατά την ανάθεση του color[n] στα bitmap[n]. Ευχαριστώ θα το κοιτάξω. Εντύπωση μου κανει που το αν θα τρέξει σωστά εχει να κάνει απλά και μονο με την υπαρξη του cout.
Directx Δημοσ. 27 Ιουνίου 2012 Δημοσ. 27 Ιουνίου 2012 Δοκίμασα επίσης με g++ από cmd αντί του codeblocks μπας και, αλλα τίποτα. Αρα παιζει σε linux και οχι σε windows.. Ενδιαφέρον. Ευχαριστώ θα το κοιτάξω. Εντύπωση μου κανει που το αν θα τρέξει σωστά εχει να κάνει απλά και μονο με την υπαρξη του cout. Ο κώδικας σου χτυπάει στην ρουτίνα Bitmap::Add κατά την ανάθεση του color[n] στα bitmap[n] διότι στο Color::char *get δοκιμάζεις να επιστρέψεις δείκτη στην τοπική μεταβλητή (πίνακα) color[3] η οποία δεν διατηρείται μετά την έξοδο της ρουτίνας (έστω και αν static) - ένα τόσο σοβαρό σφάλμα μπορεί να οδηγήσει σε παράξενη συμπεριφορά το λογισμικό. Μια γρήγορη λύση για να διατηρήσεις την διεύθυνση μνήμης του char color[3] της ::*get και μετά την έξοδο της, είναι η δήλωση του πίνακα ως static (αν και εγώ θα προτιμούσα μια γενική αναθεώρηση της Color): > static char* get(char RED, char GREEN, char BLUE) { char *pointer; static char color[3];// = {BLUE, GREEN, RED}; color[0] = BLUE; color[1] = GREEN; color[2] = RED; pointer = color; return pointer; }
Moderators Praetorian Δημοσ. 27 Ιουνίου 2012 Moderators Δημοσ. 27 Ιουνίου 2012 ^^ Βασικά και εγώ αυτό ήρθα να γράψω. Η Color έχει πρόβλημα γιατί καταστρέφεται ο πίνακας στον οποίο δείχνει ο pointer που επιστρέφεις στην get.
bnvdarklord Δημοσ. 27 Ιουνίου 2012 Μέλος Δημοσ. 27 Ιουνίου 2012 Γιατί καταστρέφεται ο πίνακας; Αυτό ειναι καλυτερο νομιζω: > static char* get(char RED, char GREEN, char BLUE) { char* color = new char[3]; color[0] = BLUE; color[1] = GREEN; color[2] = RED; return color; } Τώρα δουλευει οπως φαινεται.
Directx Δημοσ. 27 Ιουνίου 2012 Δημοσ. 27 Ιουνίου 2012 Γιατί καταστρέφεται ο πίνακας; Αυτό ειναι καλυτερο νομιζω: > static char* get(char RED, char GREEN, char BLUE) { char* color = new char[3]; color[0] = BLUE; color[1] = GREEN; color[2] = RED; return color; } Τώρα δουλευει οπως φαινεται. Με την προϋπόθεση όμως ότι θα αναθεωρήσεις τον κώδικα σου ώστε να αποδεσμεύεις το char* μετά την χρήση της ::get (new & delete) διαφορετικά θα έχεις memory leak.
migf1 Δημοσ. 27 Ιουνίου 2012 Δημοσ. 27 Ιουνίου 2012 Me την προϋπόθεση όμως ότι θα αναθεωρήσεις τον κώδικα σου ώστε να αποδεσμεύεις το char* μετά την χρήση (new & delete) διαφορετικά θα έχεις memory leak. Από το στόμα μου το πήρες Επίσης, γιατί είναι ορισμένη ως static η συνάρτηση; (σημείωση, δεν έχω δει τον υπόλοιπο κώδικα)
bnvdarklord Δημοσ. 27 Ιουνίου 2012 Μέλος Δημοσ. 27 Ιουνίου 2012 Αρα οπου χρησιμοποιώ τον κωδικά μου Color τα αναθέτω σε δείκτη, το δίνω ως παράμετρο οπου χρειάζεται, και μετά κανω delete. Σωστά; Εχω παρασυνηθίσει το garbage collection μου φαινεται Επίσης, γιατί είναι ορισμένη ως static η συνάρτηση; (σημείωση, δεν έχω δει τον υπόλοιπο κώδικα) Γιατι δεν φτιαχνω αντικείμενα Color, απλά ζητάω ενα char* με τις τιμές που δινω για rgb.
Directx Δημοσ. 27 Ιουνίου 2012 Δημοσ. 27 Ιουνίου 2012 (σημείωση, δεν έχω δει τον υπόλοιπο κώδικα) Μια από τα ίδια, μια γρήγορη ματιά έριξα συνολικά και αφού βρέθηκε το σφάλμα μετά κοίταξα να προτείνω ένα γρήγορο patch (για να μην χρειασθεί να αλλάξει το υπόλοιπο πρόγραμμα του φίλου bnvdarklord).
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα