Title: Περίεργο ERROR στη C... Post by: Faidon on May 24, 2006, 18:03:25 pm Τρέχω τον παρακάτω κώδικα και μου πετάει το κλασικό παράθυρο των Windows (Η εφαρμογή αντιμετώπισε πρόβλημα και πρέπει να τερματιστεί... κτλ):
main(){ int a,b,c,*p1,*p2; *p2=0; scanf("%i",&a); } Αντίθετα οι παρακάτω λειτουργούν κανονικά (σΣημειώνω με bold τις αλλαγές): main(){ int a,b,c,*p1,*p2; *p1=0; scanf("%i",&a); } main(){ int a,b,*p1,*p2; *p2=0; scanf("%i",&a); } Το πρόβλημα το αντιμετώπισα καθώς προσπαθούσα να κάνω την εργασία F του Δομημένου στον Dev-C++ 4.01. Γνωρίζει κανείς σε τι οφείλεται; Title: Re: Περίεργο ERROR στη C... Post by: Verminoz on May 24, 2006, 18:11:59 pm Ένα σφάλμα που βλέπω εγώ είναι ότι δεν έχεις βάλει reference στο a στην scanf...δηλαδή κανοξικά πρέπει να είναι:
scanf("%i",&a); Αλήθεια ο τύπος "%i" τι είναι??? Συνήθως όταν θέλουμε ακέραιο βάζουμε "%d"... Title: Re: Περίεργο ERROR στη C... Post by: Faidon on May 24, 2006, 18:37:19 pm Ναι το ξέχασα. Δεν είναι εκεί όμως το πρόβλημα. Η scanf() δεν τρέχει γιατί το πρόβλημα εμφανίζεται στην προηγούμενη εντολή.
Το %i=%d, και τα δύο δηλώνουν ακέραιο. Πρόβλημα βγάζουν και οι παρακάτω κώδικες: main(){ int a,b,c,d,*e; *e=0; scanf("%i",&a); } main(){ int a,b,c,d; int *e; *e=0; scanf("%i",&a); } main(){ int a,b,c,d; float *e; *e=0; scanf("%i",&a); } Τουλάχιστον όπως εγώ το βλέπω, όταν δηλώνω 4 ακεραίους και μετά μία μεταβλητή τύπου pointer. Όταν πάω να χρησιμοποιήσω την μεταβλητή αυτή (τύπου pointer) μου βγάζει σφάλμα... Τελείως περίεργο... Title: Απ: Περίεργο ERROR στη C... Post by: meltemi on May 24, 2006, 18:46:35 pm Δε μου έρχεται κάτι.
Πάντως να ξέρεις πως με borland τρέχει κανονικά. Με dev αντιμετωπίζω το ίδιο πρόβλημα με εσένα. ;) Αν κάποιος γνωρίζει ας πει παρακαλώ.. :P Title: Re: Περίεργο ERROR στη C... Post by: lambros on May 24, 2006, 18:51:19 pm Το πρόβλημα που εντοπίζω εγώ είναι ότι δεν έχεις αρχικοποιήσει τον δείκτη.Δηλαδή ορίζεις σαν δεικτή τον e ,που σημαίνει ότι αυτός περιέχει μια διεύθυνση μνήμης απροσδιόριστη όμως,δηλ δεν ξέρεις που στο διάγαλο δείχνει :o.Γι' αυτό το πρώτο πράγμα που κάνεις αφού ορίσεις ένα δείκτη είναι να του δώσεις τη διεύθυνση μιας άλλης μεταβλητής,πχ e=&d όποτε ο e δείχνει στην d και το *e=0 λειτουργεί.
EDIT:Επίσης με την malloc μπορεί να γίνει αρχικοποίηση δείκτη ,αν δεν κάνω λάθος. πχ e=(int *)malloc(sizeof(int)) Title: Re: Περίεργο ERROR στη C... Post by: Faidon on May 24, 2006, 19:40:22 pm Αυτό που λες lambros από όσο καταλαβαίνω και ξέρω δεν ισχύει.
Όταν δηλώνεις μία μεταβλητη η C δεσμεύει χώρο για τη μεταβλητή αυτή. Τη μεταβλητή τη δηλώνεις όπως σε βολέυει. Ανάλογα με το αν θες να αναφέρεσαι σε αυτή άμμεσα η στον pointer της. Όταν δηλώνεις int *e. Δηλώνεις το περιεχόμενο του (pointer) e. Δηλαδή, δεσμέυεται ο χώρος για έναν ακέραιο και αντί να σου δώσει ένα συμβολικό όνομα του χώρου, η C σου επιστρέφει την τιμή του pointer που δείχνει στο χώρο. Προφανώς αυτό που γράφεις θα λειτουργήσει. Αλλά έτσι διαγράφεις τη μεταβλητή *e που εγώ θέλω να χρησιμοποιήσω. Στην ουσία έχεις 4 ακέραιες μεταβλητές και έναν pointer που δείχνει στη τελευταία. Αυτό είναι άχρηστο. Ούτως ή άλλως ο pointer που δείχνει στην τελευταία είναι δηλωμένος και γνωστός (&d). Εξάλλου ο παρακάτω κώδικα λειτουργεί κανονικά χωρίς να δώσω στον pointer τη διέυθυνση άλλης μεταβλητής όπως προτείνεις: main(){ int a,*b; *b=0; printf("%i",*b); scanf("%i",&a); } Το περιεχόμενο του pointer b (*b) παίρνει την τιμή 0 και την εκτυπώνει κανονικά. Το πρόβλημα θα είναι μάλλον στο λογισμικό του Dev-C++ 4.01. Ας το δοκιμάσει και όποιος έχει νεότερη version του Dev-C++ Title: Απ: Περίεργο ERROR στη C... Post by: meltemi on May 24, 2006, 20:02:04 pm Χρησιμοποιώ την 4.9.9.2 και βγάζει το ίδιο...
Να σε πω, αντί για *b=0 δε δοκιμάζεις μια απλή εκχώρηση b=0; Τον δηλώνεις ως pointer ok αλλά έχω την εντύπωση οτι η εκχώρηση αυτή προκαλλεί το πρόβλημα. Νο problem using Borland of course... Title: Re: Περίεργο ERROR στη C... Post by: michaelidesc on May 24, 2006, 20:06:21 pm main(){
int a,b,c,*p1,*p2; p2=0; scanf("%i",&a); } Title: Απ: Περίεργο ERROR στη C... Post by: meltemi on May 24, 2006, 20:07:05 pm main(){ int a,b,c,*p1,*p2; p2=0; scanf("%i",&a); } ;) ;) Title: Re: Περίεργο ERROR στη C... Post by: 4Dcube on May 24, 2006, 20:08:58 pm Μήπως παίζει τίποτε με δεσμευμένες λέξεις;
Θυμάμαι σε κάποιον κομπάιλερ δεν πιανόταν το Ν. Title: Απ: Περίεργο ERROR στη C... Post by: meltemi on May 24, 2006, 20:10:17 pm Μήπως παίζει τίποτε με δεσμευμένες λέξεις; Θυμάμαι σε κάποιον κομπάιλερ δεν πιανόταν το Ν. :-\ Don't think so dear cube. ^kissy^ Title: Re: Περίεργο ERROR στη C... Post by: michaelidesc on May 24, 2006, 22:13:45 pm Συγχωρήστε με που ήμουν εκτός, βιάστηκα να απαντήσω και είπα βλακεία, δεν είχα αντιληφθεί ποιο ήταν το πρόβλημα. Ο lambros έχει δίκιο. Το *p2=0; δεν έχει νόημα εφόσον δεν δείχνει πουθενά. Αντιστοίχησέ το πρώτα σε μια διεύθυνση μεταβλητής π.χ. p2=&a και θα τρέξει μια χαρά. Ψάξε το στην "Αλεξάνδρεια" (Α/Α 245).
Title: Απ: Περίεργο ERROR στη C... Post by: meltemi on May 24, 2006, 22:24:17 pm Συγχωρήστε με που ήμουν εκτός, βιάστηκα να απαντήσω και είπα βλακεία, δεν είχα αντιληφθεί ποιο ήταν το πρόβλημα. Ο lambros έχει δίκιο. Το *p2=0; δεν έχει νόημα εφόσον δεν δείχνει πουθενά. Αντιστοίχησέ το πρώτα σε μια διεύθυνση μεταβλητής π.χ. p2=&a και θα τρέξει μια χαρά. Ψάξε το στην "Αλεξάνδρεια" (Α/Α 245). Τhanks pal ;) Title: Re: Περίεργο ERROR στη C... Post by: Faidon on May 25, 2006, 00:50:07 am Ναι ρε, michaelidesc, αλλά όπως λέω πιο πάνω:
O παρακάτω κώδικα λειτουργεί κανονικά χωρίς να δώσω στον pointer τη διέυθυνση άλλης μεταβλητής όπως προτείνεις: main(){ int a,*b; *b=0; printf("%i",*b); scanf("%i",&a); } Το περιεχόμενο του pointer b (*b) παίρνει την τιμή 0 και την εκτυπώνει κανονικά. Δηλαδή, δεν απαιτείται αρχικοποίηση όπως λέει ο lambros... Title: Απ: Περίεργο ERROR στη C... Post by: BOBoMASTORAS on May 25, 2006, 01:00:28 am Ναι ρε συ. Το θέμα είναι ότι δεν έχεις δεσμέυσει μνήμη στη θέση για να αποθηκευτεί η τιμή μηδέν. Ο pointer b είναι μία μεταβλητή η οποία δε δείχνει "πουθενά" (βασικά δείχνει κάπου αλλά ούτε ξέρουμε που ούτε η μνήμη σε αυτό το σημείο είναι δεσμευμένη για χρήση από το πρόγραμμα μας)
Title: Re: Περίεργο ERROR στη C... Post by: Faidon on May 25, 2006, 02:42:15 am O παρακάτω κώδικα λειτουργεί κανονικά χωρίς να δώσω στον pointer τη διέυθυνση άλλης μεταβλητής όπως προτείνεις: main(){ int a,*b; *b=0; printf("%i",*b); scanf("%i",&a); } Το περιεχόμενο του pointer b (*b) παίρνει την τιμή 0 και την εκτυπώνει κανονικά. Τότε γιατί αυτός ο κώδικας τρέχει κανονικά;; Title: Απ: Περίεργο ERROR στη C... Post by: BOBoMASTORAS on May 25, 2006, 03:18:41 am Εντελώς τυχαίο..... Ο b έχει σκουπίδια δε ξέρεις που δείχνει....
Γενικά τα windows σα λειτουργικό καταγράφουν τις θέσεις μνήμης που έχει δεσμεύσει ένα πρόγραμμα. Αν προσπαθήσει να γράψει σε διεύθυνση που δεν έχει δεσμέσει βγάζει το μήνυμα που ανέφερε ο συνάδελφος. υπάρχει όμως πάντα το ενδεχόμενο η θέση μνήμης να έχει δεσμευτέι από το πρόγραμμα και να είναι κάποια άλλη μεταβλητή ή ακόμα και κώδικας. Τότε τα widows δε θα βγάλουν error. Αν δοκιμάσεις να τρέξεις το exe εκτός του compiler είναι πολύ πιθανό μερικές φορές να βγάζεις ερρορ και αλλές όχι Title: Απ: Περίεργο ERROR στη C... Post by: meltemi on May 25, 2006, 08:35:31 am Γενικά τα windows σα λειτουργικό καταγράφουν τις θέσεις μνήμης που έχει δεσμεύσει ένα πρόγραμμα. Αν προσπαθήσει να γράψει σε διεύθυνση που δεν έχει δεσμέσει βγάζει το μήνυμα που ανέφερε ο συνάδελφος. υπάρχει όμως πάντα το ενδεχόμενο η θέση μνήμης να έχει δεσμευτέι από το πρόγραμμα και να είναι κάποια άλλη μεταβλητή ή ακόμα και κώδικας. Τότε τα widows δε θα βγάλουν error. Αν δοκιμάσεις να τρέξεις το exe εκτός του compiler είναι πολύ πιθανό μερικές φορές να βγάζεις ερρορ και αλλές όχι Σε αυτό κατέληξα κι εγώ. :( Ευχαριστούμε Bob. ^kissy^ ^kissy^ Title: Re: Περίεργο ERROR στη C... Post by: Faidon on May 25, 2006, 14:00:08 pm Επιτέλους το κατάλαβα...
Ο παρακάτω κώδικας δεν τρέχει ΠΟΤΕ σωστά, όπως είπα βγάζει error: main(){ int a,b,c,d,*e; *e=1; printf("%i",*e); scanf("%i",&a); } Οι παρακάτω όμως τρέχουν ΠΑΝΤΑ κανονικά, στο δικό μου PC τουλάχιστον: main(){ int a,b,c,d,f,g,h,t,y,u,i,*e; *e=1; printf("%i",*e); scanf("%i",&a); } main(){ int a,*e; *e=1; printf("%i",*e); scanf("%i",&a); } Εγώ καταλήγω στο συμπέρασμα (σύμφωνα με αυτα που λέτε) ότι όταν δηλώνεις μία μεταβλητή απλή ή pointer, η C δεσμεύει χώρο για αυτήν ή το περιεχόμενο του pointer. Αν όμως αυτό το περιεχόμενο του pointer δεν σου επιτρέπουν τα WINDOWS να το χρησιμοποιήσεις βγάζει error. Τότε στον συγκεκριμένο κώδικα το περιεχόμενο του pointer, όταν τον δηλώνω πέμπτο, είναι τέτοιο που τα WINDOWS δε μου επιτρέπουν να το χρησιμοποιήσω. Αντίθετα όταν δηλώνω τον pointer δέυτερο ή δωδέκατο το περιεχόμενο του είναι τέτοιο που τα WINDOWS μου επιτρέπουν να το χρησιμοποιήσω. Έτσι είναι; Title: Απ: Περίεργο ERROR στη C... Post by: BOBoMASTORAS on May 25, 2006, 14:07:40 pm Εγώ καταλήγω στο συμπέρασμα (σύμφωνα με αυτα που λέτε) ότι όταν δηλώνεις μία μεταβλητή απλή ή pointer, η C δεσμεύει χώρο για αυτήν η το περιεχόμενο του pointer. Αν όμως αυτό το περιεχόμενο του pointer δεν σου επιτρέπουν τα WINDOWS να το χρησιμοποιήσεις βγάζει error. πάντοτε δεσμεύεις μνήμη απλά για την μεταβλητή σου. έτσι όταν δηλώνεις ένας pointer δεσμέυεις μνήμη για να αποθηκευτεί η διεύθυνση στην οποία θέλεις να γράψεις (πχ αποθηκεύεται το 100 ως διεύθυνση μνήμης) Το αν η συγκεκριμένη θέση μνήης είναι δευσμευμένη είναι κάτι το οποίο πρέπει να το φροντ΄'ισεις εσύ. δηλαδή μπορεί να μην έχεις δεσμεύσει την θέση 100 ώστε να γράψεις σε αυτήν Τότε το περιεχόμενο του pointer (όταν των δηλώνω πέμπτο) είναι τέτοιο που τα WINDOWS δε σου επιτρέπουν να το χρησιμοποιήσεις. Αντίθετα όταν δηλώνω τον pointer δέυτερο ή δωδέκατο το περιεχόμενο του είναι τέτοιο που τα WINDOWS σου επιτρέπουν να το χρησιμοποιήσεις. Έτσι είναι; Η σειρά μπορεί να αλλάξει ανάλογα με τον compiler που χρησιμοποιείς την αρχιτεκτονική του υπολογιστή σου το λειτουργικό που χρησημοποιείς και πολλά άλλα. Δε μπορείς να καταλήξεις σε ένα στάνταρ κανόνα. Title: Re: Περίεργο ERROR στη C... Post by: cybegar on May 25, 2006, 15:08:09 pm Όταν χρησιμοποιείς μια μεταβλητή τύπου pointer απλά για να της αναθέσεις την διεύθυνση ενός
άλλου pointer, τότε δεν χρειάζεται να κάνεις δυναμική κατανομή της μνήμης(malloc(C)/new(C++)). Εάν όμως σκοπεύεις να δώσεις τιμές στην διεύθυνση της μεταβλητής τύπου pointer που ορίζεις, τότε σαφώς και πρέπει να δεσμεύσεις δυναμικά μνήμη ώστε να αποθηκευθούν τα δεδομένα σου. Ανάλογα με τον compiler που χρησιμοποιείς, το πρόγραμμα μπορεί άλλοτε να κάνει compile και να τρέχει δημιουργώντας errors στο λειτουργικό και άλλοτε να μην τρέχει καθόλου. Π.χ. είχα έναν pointer x (int *x) ο οποίος κρατούσε κάποια τιμή. Αν δημιουργήσω ένα νέο pointer int *n και κάνω assign n = x; τότε δεν έχω πρόβλημα. Αν όμως θέλω να δημιουργήσω το n και να του δώσω τιμή int *n *n=10; τότε έχω! Χρειάζεται προηγουμένως: n = (int)malloc(sizeof(int); Title: Re: Περίεργο ERROR στη C... Post by: lambros on May 25, 2006, 17:28:07 pm Σωστά :) . Στη C πρέπει να έχουμε πάντα το νου μας για τα σκουπίδια.Αν για παράδειγμα γράψω int k θα μου δεσμέυσει μνήμη για το k , αλλά άμα εκτυπώσω τα περιεχόμενα του δεν θα είναι 0 αλλά κάτι άσχετο.Ανάλογα η int *k δεσμεύει μνήμη για τον δείκτη k,αλλά αυτή η θέση μνήμης θα περιέχει "σκουπίδι" .Έτσι όπως στη πρώτη περίπτωση θα βάζαμε πχ k=10 για να αρχικοποιήσουμε τη μεταβλητή , έτσι και στην περίπτωση του δείκτη πρέπει να του δώσουμε μια συγκεκριμένη διεύθυνση.
Δηλαδή είτε χρησιμοποιείς μια επιπλέον μεταβλητή ( int *e,ptr; //ptr η επιπλέον μεταβλητή e=&ptr; *e=1; ) είτε με τη malloc. |