Evgenios1 Δημοσ. 22 Αυγούστου 2010 Δημοσ. 22 Αυγούστου 2010 O ms μου βγαζει 120 errors Γραψε λαθος, το εβαλα σε c extension. Αλλαξε το "rw" σε "r+" (στο fopen) 1)Αλλαξα το return Στη load_TSP_data se NULL 2) Τη main > //debug load_TSP_data(&problem, filename); //init_ants_place(&op); init_ants_place(&problem); και δουλευει μια χαρα.
Evgenios1 Δημοσ. 22 Αυγούστου 2010 Δημοσ. 22 Αυγούστου 2010 O ms μου βγαζει 120 errors Γραψε λαθος, το εβαλα σε c extension. Αλλαξε το "rw" σε "r+" (στο fopen) 1)Αλλαξα το return Στη load_TSP_data se NULL 2) Τη main > //debug load_TSP_data(&problem, filename); //init_ants_place(&op); init_ants_place(&problem); και δουλευει μια χαρα. [ATTACH]33773[/ATTACH]
Dr.Fuzzy Δημοσ. 22 Αυγούστου 2010 Μέλος Δημοσ. 22 Αυγούστου 2010 O ms μου βγαζει 120 errorsΓραψε λαθος, το εβαλα σε c extension. Αλλαξε το "rw" σε "r+" (στο fopen) 1)Αλλαξα το return Στη load_TSP_data se NULL 2) Τη main > //debug load_TSP_data(&problem, filename); //init_ants_place(&op); init_ants_place(&problem); και δουλευει μια χαρα. [ATTACH]33773[/ATTACH] Πράγματι έτσι δουλεύει, μόλις το δοκίμασα και εγώ. Thanx. Το θέμα είναι πώς θα δουλέψει με το περίεργο return του struct member (return problem->node) που κάνω και γιατί μου πετάει seg.fault. Εδώ σε θέλω μάστορα!
Dr.Fuzzy Δημοσ. 22 Αυγούστου 2010 Μέλος Δημοσ. 22 Αυγούστου 2010 O ms μου βγαζει 120 errorsΓραψε λαθος, το εβαλα σε c extension. Αλλαξε το "rw" σε "r+" (στο fopen) 1)Αλλαξα το return Στη load_TSP_data se NULL 2) Τη main > //debug load_TSP_data(&problem, filename); //init_ants_place(&op); init_ants_place(&problem); και δουλευει μια χαρα. [ATTACH]33773[/ATTACH] Πράγματι έτσι δουλεύει, μόλις το δοκίμασα και εγώ. Thanx. Το θέμα είναι πώς θα δουλέψει με το περίεργο return του struct member (return problem->node) που κάνω και γιατί μου πετάει seg.fault. Εδώ σε θέλω μάστορα!
Evgenios1 Δημοσ. 23 Αυγούστου 2010 Δημοσ. 23 Αυγούστου 2010 Κανε return problem; Αλλα σου λεω πως δεν χρειαζεται. ΥΓ: Για να ειναι πιο "ευχαριστος" ο κωδικας σε τριτους (οπος εγω), χρησιμοποιησε το typedef στους structs πχ >typedef struct { double x; double y; } POINT,*PPOINT; typedef struct { char name[LINE_BUFFER_LENGTH]; char edge_weight_type[LINE_BUFFER_LENGTH]; long int n; PPOINT node; }TSP_DATA,*PTSP_DATA; PTSP_DATA load_TSP_data(PTSP_DATA problem, const char *TSP_filename)...
Evgenios1 Δημοσ. 23 Αυγούστου 2010 Δημοσ. 23 Αυγούστου 2010 Κανε return problem; Αλλα σου λεω πως δεν χρειαζεται. ΥΓ: Για να ειναι πιο "ευχαριστος" ο κωδικας σε τριτους (οπος εγω), χρησιμοποιησε το typedef στους structs πχ >typedef struct { double x; double y; } POINT,*PPOINT; typedef struct { char name[LINE_BUFFER_LENGTH]; char edge_weight_type[LINE_BUFFER_LENGTH]; long int n; PPOINT node; }TSP_DATA,*PTSP_DATA; PTSP_DATA load_TSP_data(PTSP_DATA problem, const char *TSP_filename)...
imitheos Δημοσ. 23 Αυγούστου 2010 Δημοσ. 23 Αυγούστου 2010 Ναι και εγώ παίρνω segmentation fault και είναι λογικό. Εφόσον έχεις βάλει να επιστρέφει την node πρέπει να το return type να είναι struct point* (έστω προσωρινά μέχρι να υλοποιήσεις τα υπόλοιπα). Αλλάζοντας το return type της load_TSP_data και προσθέτοντας/αλλάζοντας > op=malloc(sizeof(struct TSP_data)); op->node = load_TSP_data(&problem, filename); παίρνω το αποτέλεσμα > node x: 25.000 Αν αλλάξω το return type σε void και δεν χρησιμοποιήσω καθόλου την μεταβλητή op, παίρνω και πάλι > node x: 25.000
imitheos Δημοσ. 23 Αυγούστου 2010 Δημοσ. 23 Αυγούστου 2010 Ναι και εγώ παίρνω segmentation fault και είναι λογικό. Εφόσον έχεις βάλει να επιστρέφει την node πρέπει να το return type να είναι struct point* (έστω προσωρινά μέχρι να υλοποιήσεις τα υπόλοιπα). Αλλάζοντας το return type της load_TSP_data και προσθέτοντας/αλλάζοντας > op=malloc(sizeof(struct TSP_data)); op->node = load_TSP_data(&problem, filename); παίρνω το αποτέλεσμα > node x: 25.000 Αν αλλάξω το return type σε void και δεν χρησιμοποιήσω καθόλου την μεταβλητή op, παίρνω και πάλι > node x: 25.000
Dr.Fuzzy Δημοσ. 23 Αυγούστου 2010 Μέλος Δημοσ. 23 Αυγούστου 2010 Credits & Thanx to Evgenios1 και imitheos για το χρόνο σας. Όντος είναι περιττό να κάνω return problem αφού κάνω pass arguments by reference. Το κόλλημα του ΗW μηχανικού βλέπετε, ένα ιεραρχικό block με εισόδους και εξόδους! @Evgenios1 Το implementation με typedef struct το είχα στο μυαλό μου, αλλά να σου πω την αλήθεια δεν το συμπάθησα ποτέ ιδιαίτερα, μου φαίνεται ότι ο κώδικας γίνεται πιο δυσανάγνωστος. Φυσικά μπορεί να κάνω και λάθος.
Dr.Fuzzy Δημοσ. 23 Αυγούστου 2010 Μέλος Δημοσ. 23 Αυγούστου 2010 Credits & Thanx to Evgenios1 και imitheos για το χρόνο σας. Όντος είναι περιττό να κάνω return problem αφού κάνω pass arguments by reference. Το κόλλημα του ΗW μηχανικού βλέπετε, ένα ιεραρχικό block με εισόδους και εξόδους! @Evgenios1 Το implementation με typedef struct το είχα στο μυαλό μου, αλλά να σου πω την αλήθεια δεν το συμπάθησα ποτέ ιδιαίτερα, μου φαίνεται ότι ο κώδικας γίνεται πιο δυσανάγνωστος. Φυσικά μπορεί να κάνω και λάθος.
imitheos Δημοσ. 23 Αυγούστου 2010 Δημοσ. 23 Αυγούστου 2010 Credits & Thanx to Evgenios1 και imitheos για το χρόνο σας. Όντος είναι περιττό να κάνω return problem αφού κάνω pass arguments by reference. Το κόλλημα του ΗW μηχανικού βλέπετε, ένα ιεραρχικό block με εισόδους και εξόδους! Εντάξει δεν έκανες και κάτι κακό . Το πως θα υλοποιηθεί κάτι εξαρτάται από τον προγραμματιστή. Επίσης υπάρχουν περιπτώσεις που χρειάζεται το return (πχ αν ήθελες να πειράξεις τον pointer). @Evgenios1 Το implementation με typedef struct το είχα στο μυαλό μου, αλλά να σου πω την αλήθεια δεν το συμπάθησα ποτέ ιδιαίτερα, μου φαίνεται ότι ο κώδικας γίνεται πιο δυσανάγνωστος. Φυσικά μπορεί να κάνω και λάθος. Και καλά έκανες γιατί _είναι_ δυσανάγνωστο. > PTSP_DATA load_TSP_data(PTSP_DATA problem, const char *TSP_filename) Δες τώρα αυτό. Τι είναι το PTSP_DATA ? Κανείς δεν ξέρει. Μπορεί να είναι integer μπορεί να είναι pointer σε float, μπορεί να είναι δομή (όπως και είναι). Τα typedef είναι χρήσιμα μόνο για να αποκρύψουν λεπτομέρειες που δεν χρειάζονται μειώνοντας έτσι την πολυπλοκότητα (abstraction επί το ελληνικότερον) π.χ οι τύποι της C99. Ξέρεις ότι το uint32_t είναι unsigned και έχει εύρος 32bit. Δεν χρειάζεται να ξέρεις τι είναι από κάτω. (Και σε αυτή την περίπτωση ακόμη ούτε καν είναι typedef. #define macro είναι) Όταν είχα κάνει το TSP με γενετικούς αλγορίθμους, ο καθηγητής ήθελε να ορίσουμε τα πάντα με typedefs "για να είναι πιο ευανάγνωστο", έτσι είχαμε > typedef int gonidio; typedef gonidio plh8ismos[100]; και άλλες τέτοιες χαζομάρες. Όπου μπορείς να αποφύγεις typedefs, κάντο.
imitheos Δημοσ. 23 Αυγούστου 2010 Δημοσ. 23 Αυγούστου 2010 Credits & Thanx to Evgenios1 και imitheos για το χρόνο σας. Όντος είναι περιττό να κάνω return problem αφού κάνω pass arguments by reference. Το κόλλημα του ΗW μηχανικού βλέπετε, ένα ιεραρχικό block με εισόδους και εξόδους! Εντάξει δεν έκανες και κάτι κακό . Το πως θα υλοποιηθεί κάτι εξαρτάται από τον προγραμματιστή. Επίσης υπάρχουν περιπτώσεις που χρειάζεται το return (πχ αν ήθελες να πειράξεις τον pointer). @Evgenios1 Το implementation με typedef struct το είχα στο μυαλό μου, αλλά να σου πω την αλήθεια δεν το συμπάθησα ποτέ ιδιαίτερα, μου φαίνεται ότι ο κώδικας γίνεται πιο δυσανάγνωστος. Φυσικά μπορεί να κάνω και λάθος. Και καλά έκανες γιατί _είναι_ δυσανάγνωστο. > PTSP_DATA load_TSP_data(PTSP_DATA problem, const char *TSP_filename) Δες τώρα αυτό. Τι είναι το PTSP_DATA ? Κανείς δεν ξέρει. Μπορεί να είναι integer μπορεί να είναι pointer σε float, μπορεί να είναι δομή (όπως και είναι). Τα typedef είναι χρήσιμα μόνο για να αποκρύψουν λεπτομέρειες που δεν χρειάζονται μειώνοντας έτσι την πολυπλοκότητα (abstraction επί το ελληνικότερον) π.χ οι τύποι της C99. Ξέρεις ότι το uint32_t είναι unsigned και έχει εύρος 32bit. Δεν χρειάζεται να ξέρεις τι είναι από κάτω. (Και σε αυτή την περίπτωση ακόμη ούτε καν είναι typedef. #define macro είναι) Όταν είχα κάνει το TSP με γενετικούς αλγορίθμους, ο καθηγητής ήθελε να ορίσουμε τα πάντα με typedefs "για να είναι πιο ευανάγνωστο", έτσι είχαμε > typedef int gonidio; typedef gonidio plh8ismos[100]; και άλλες τέτοιες χαζομάρες. Όπου μπορείς να αποφύγεις typedefs, κάντο.
Dr.Fuzzy Δημοσ. 24 Αυγούστου 2010 Μέλος Δημοσ. 24 Αυγούστου 2010 άλλο ένα θεματάκι και ελπίζω να μην σας έχω πρήξει! Λοιπόν έστω ότι έχω το παρακάτω function που κάνει allocate δυναμικά μνήμη για ένα array. > /* * initial ants placement */ int* init_ants_place(struct TSP_data *problem) { int i; time_t *now; srand(time(now)); // randomness depends on time int *ants_place; ants_place = (int *) malloc(problem->n*sizeof(int)); // allocate placement memory (n int elements) dynamically // debug if (ants_place != 0) { printf("Allocation of %d bytes was successful\n\n", problem->n*sizeof(int)); } else { fprintf(stderr, "\nERROR: Attempt to allocate %d bytes failed !\n",problem->n*sizeof(int)); exit(1); } // for (i=0; i<problem->n; i++) { ants_place[i] = rand() % (problem->n -1) + 1; // place ants randomly printf("Random ant %d placement: %d \n", i, ants_place[i]); // debug //printf("node x: %G node y: %G\n", problem->node[ants_place[i]].x, problem->node[ants_place[i]].y); // debug } //printf("ith ant placement: %d\n", *(++ants_place)); // debug return ants_place; } αφού λοιπόν καλώ το function στη main και κάνει μια χαρά τη δουλειά του, αποφασίζω να κάνω free την memory που δέσμευσε και επειδή μου αρέσει να τα έχω σε functions και όχι χύμα μέσα στη main, καλώ την παρακάτω. > /* * free ants placement */ free_ants_place(int *ants_place, struct TSP_data *problem) { while (ants_place != 0) { //ants_place = NULL; free(ants_place); } και τρώω ένα ωραίο...seg.fault πιθανά διότι δεν γνωρίζει πόσο μέγεθος έχει το ants_place (είναι array)..εικάζω! Οπότε δοκίμασα να περναώ και το &problem και να τρέξω for loop i=0 -> i=promblem->n και να κάνω free(ants_array), αλλά τα ίδια...
imitheos Δημοσ. 24 Αυγούστου 2010 Δημοσ. 24 Αυγούστου 2010 > time_t *now; srand(time(now)); // randomness depends on time Εμένα πάλι τρώει το segfault εδώ. Αν το κάνω srand(time(NULL)) δουλεύει.
Evgenios1 Δημοσ. 25 Αυγούστου 2010 Δημοσ. 25 Αυγούστου 2010 Η free περνει παραμετρο εναν pointer οποιος δειχνει ενα μπλοκ μνημης το οποιο ειναι allocated. Δεν χρειαζεται να ξερεις το μεγεθος της μνημης! Η free δεν σκαει μονο οταν ο δεικτης ειναι NULL ή οταν δειχνει ενα allocated block. Προσοχη! Η free ΔΕΝ μηδενιζει τον δεικτη, με αποτελεσμα αν ξανακαλεσεις την free να σκασει. (Αυτο ακριβος κανεις εσυ με το while loop) Ενα απολο allocate/deallocate ειναι το παρακατω >int main(int argc, char** argv) { int *i = (int*) malloc(8); free(i); } Πιο συνθετο deallocate, με μηδενισμο του δεικτη >void safe_free(int **m) { if(*m!=NULL) { free(*m); *m = NULL; } } int main(int argc, char** argv) { int *i = (int*) malloc(8); safe_free(&i); safe_free(&i); safe_free(&i); safe_free(&i); return 0; } Επεισης στο κομματι αυτο > time_t *now; srand(time(now)); // randomness depends on time Μπορει να προκυψει προβλημα, το οποιο εξαρταται απο τον compiler*. Για αυτο αλλαξε το σε time(NULL) ή time_t t; time(&t); *Πχ ο δικος μου το time_t *now; θα το μεταφρασει σε time_t *now = 0xcdcdcdcd; με αποτελεσμα να μου πεταει ανα μνμ ο debugger, οτι το now δεν εχει παρει καπια τιμη. Ο δικος σου λογικα θα το μεταφραζει σε time_t *now = 0;
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.