Εμφάνιση 1-13 από 13
  1. #1
    Εγγραφή
    21-03-2008
    Ηλικία
    36
    Μηνύματα
    9.890
    Downloads
    8
    Uploads
    2
    Τύπος
    VDSL2
    Ταχύτητα
    51200/5120
    ISP
    Nova
    Router
    VMG8623-T50B & Debian
    Γεια σας, έχω τον εξής κώδικα:

    Κώδικας:
    void NewDoc() {
        system("clear"); // Εκκαθάριση οθόνης
        cout << "Εισαγωγή γιατρού\n--------------------\n" << endl;
        cout << "Όνομα:     ";
        string inp;
        cin >> inp;
        int i=0;
        while (Doctors[i]!=NULL)
        {if (!Doctors[i]->name.compare(inp)) 
        {cout << "Υπάρχει ήδη γιατρός με όνομα """ << inp << """. Δεν γίνεται εισαγωγή"; sleep(2000); menu();}
        else i++;
        }
        i=0; while (Doctors[i]!=NULL) {i++;}
        Doctors[i] = new Doc;
        Doctors[i]->name = inp;
        if (!Doctors[i]->name.compare(inp)) {cout << "Η εισαγωγή ολοκληρώθηκε."; sleep(2000); menu();} 
        else {cout << "Η εισαγωγή δεν ολοκληρώθηκε."; sleep(2000); NewDoc();}
    }
    Μετά το cin >> inp; μου πετάει segmentation fault. Το compile γίνεται χωρίς σφάλματα, σε KDevelop (Kubuntu 8.04). Τι μπορεί να φταίει; Ώς αρχικές δηλώσεις του προγράμματος έχω τις εξής:

    Κώδικας:
    #include <iostream>
    
    using namespace std;
    Ο υπόλοιπος κώδικας ίσως είναι λίγο μπακαλίστικος, αλλά αυτή τη στιγμή με διαολίζει αυτό το segfault.

    Ευχαριστώ εκ των προτέρων για κάθε βοήθεια
    Τελευταία επεξεργασία από το μέλος Simpleton : 29-06-08 στις 23:23.
    - Κάνετε τη δουλειά σας γρήγορα, αξιόπιστα, με ασφάλεια, χωρίς τεχνητούς περιορισμούς και δωρεάν με το Linux.
    - Οι δίσκοι χαλάνε! Σκεφτείτε τα αρχεία σας πριν την πατήσετε. Κάνετε τακτικά backup.

  2. #2
    Εγγραφή
    17-09-2007
    Ηλικία
    47
    Μηνύματα
    865
    Downloads
    1
    Uploads
    0
    Καλημέρα,

    Σου πετάει ακριβώς μετά το "cin >> inp" ή απλά κάπου μετά; Τρέξε το σε έναν debugger ή βάλε cout μετά από κάθε εντολή να δείς που ακριβώς έχει πρόβλημα (πχ Doctors != NULL).

    Το έτρεξα ως και το "cin >> inp" και δεν παρουσίασε πρόβλημα...

  3. #3
    Εγγραφή
    21-03-2008
    Ηλικία
    36
    Μηνύματα
    9.890
    Downloads
    8
    Uploads
    2
    Τύπος
    VDSL2
    Ταχύτητα
    51200/5120
    ISP
    Nova
    Router
    VMG8623-T50B & Debian
    Ευχαριστώ για την απάντηση

    Εχτές μου το πέταγε αμέσως μόλις γράψω κάτι και πατήσω Enter στο prompt του "cin >> inp".

    Σήμερα που το δοκίμασα πάλι, δεχόταν ό,τι έγραφα στο prompt, αλλά μετά δεν έκανε τίποτα. Ένα
    Κώδικας:
    cout << "OK";
    μετά το "cin >> inp;" δεν έβγαζε το αντίστοιχο μήνυμα.

    Τροποποίησα την ενότητα ως εξής:
    Κώδικας:
    void NewDoc() {
    	system("clear"); // Εκκαθάριση οθόνης
    	cout << "Εισαγωγή γιατρού\n--------------------\n" << endl;
    	cout << "Όνομα:     ";
    	string inp;
    	cin >> inp;
    	cout << inp;
    }
    Τώρα δέχεται κανονικά το όνομα που βάζω και μου το εμφανίζει μέσω της cout. Δεν καταλαβαίνω αφενός πώς άλλαξε συμπεριφορά από τη μία μέρα στην άλλη, αφετέρου τι μπορεί να το ενοχλεί στον υπόλοιπο κώδικα, ώστε να μην εκτελεί καν την cin.

    Τα αντικείμενα string δεν χρειάζονται κάποια αρχικοποίηση, έτσι;
    - Κάνετε τη δουλειά σας γρήγορα, αξιόπιστα, με ασφάλεια, χωρίς τεχνητούς περιορισμούς και δωρεάν με το Linux.
    - Οι δίσκοι χαλάνε! Σκεφτείτε τα αρχεία σας πριν την πατήσετε. Κάνετε τακτικά backup.

  4. #4
    Εγγραφή
    17-09-2007
    Ηλικία
    47
    Μηνύματα
    865
    Downloads
    1
    Uploads
    0
    Φίλε skaf το πρόβλημά σου είναι εδώ:

    Κώδικας:
        while (Doctors[i]!=NULL)
        {if (!Doctors[i]->name.compare(inp)) 
        {cout << "Υπάρχει ήδη γιατρός με όνομα """ << inp << """. Δεν γίνεται εισαγωγή"; sleep(2000); menu();}
        else i++;
        }
    Συγκεκριμένα το while δε σταματάει ποτέ (οπότε όταν φτάσει σε μνήμη που δεν κατέχεις, πετάει segfault).

    Επιπλέον 99% χρησιμοποιείς με λάθος τρόπο την έξοδο "menu()": Η NewDoc() δεν επιστρέφει ποτέ, αλλά καλεί μιαν άλλη συνάρτηση. Αν κληθεί αρκούντως πολλές φορές θα μπουκώσει η στοίβα (stack). Εδώ αυτό δεν πρόκειται να γίνει, αλλά αν δεν το ξέρεις θα το κάνεις και αλλού. Πιο σωστό θα ήταν κάτι του στύλ:

    Κώδικας:
    int entryValidates = 1;
    while (Doctors[i]!=NULL && i < lengthOfDoctorsArray)
    {
      if (!Doctors[i]->name.compare(inp)) {
        cout << "Υπάρχει ήδη γιατρός με όνομα """ << inp << """. Δεν γίνεται εισαγωγή";
        sleep(2000);
        entryValidates = 0;
        break;
      }
      i++;
    }
    if( !entryValidates ) {
      return -1;
    }
    Εδώ με επιστροφή -1 σημειώνεται το λάθος στο υπόλοιπο πρόγραμμα, το οποίο και είναι υπεύθυνο για την κλήση της menu().

    Αλλά γιατί δεν τύπωνε το ΟΚ;;; Κλασικό: Τα standard streams είναι buffered, δηλαδή δε γράφουν αμέσως αυτό που τους δίνεις στην έξοδό τους. Όταν λοιπόν πεταγόταν το segfault, το "ΟΚ" ήταν στο buffer και δεν είχε προλάβει να πάει στην οθόνη. Το πρόγραμμα τερμάτιζε βεβιασμένα και οι buffers πετάγονταν, με αποτέλεσμα το μήνυμα να χάνεται. Θα το έβλεπες αν είχες κάνει κάτι του στύλ: "cout << inp; cout.flush();"

    Καλή συνέχεια

  5. #5
    Εγγραφή
    21-03-2008
    Ηλικία
    36
    Μηνύματα
    9.890
    Downloads
    8
    Uploads
    2
    Τύπος
    VDSL2
    Ταχύτητα
    51200/5120
    ISP
    Nova
    Router
    VMG8623-T50B & Debian
    Για να μην παραθέτω επιλεκτικά και ψαχνόμαστε, ιδού ολόκληρος ο κώδικας του προγράμματος:

    Spoiler:
    Κώδικας:
    #include <iostream>
    
    using namespace std;
    
    void menu();
    
    class Doc {
        public:
            string name;
            int appt[30][8];
            Doc() {
                int i, j; for(i=0; i<30; i++) {for(j=0; j<8; j++) appt[i][j]=0;} // Αρχικοποίηση ραντεβού
            }
    }*Doctors[100]; //Πίνακας δεικτών σε αντικείμενα Doc
    
    class Pat {
        public:
            string name;
            int year, month, day, appt;
    };
    
    void NewDoc() {
        system("clear"); // Εκκαθάριση οθόνης
        cout << "Εισαγωγή γιατρού\n--------------------\n" << endl;
        cout << "Όνομα:     ";
        string inp;
        cin >> inp;
        int i=0;
        while (Doctors[i]!=NULL)
        {if (!Doctors[i]->name.compare(inp)) 
        {cout << "Υπάρχει ήδη γιατρός με όνομα """ << inp << """. Δεν γίνεται εισαγωγή"; sleep(2000); menu();}
        else i++;
        }
        i=0; while (Doctors[i]!=NULL) {i++;}
        Doctors[i] = new Doc;
        Doctors[i]->name = inp;
        if (!Doctors[i]->name.compare(inp)) {cout << "Η εισαγωγή ολοκληρώθηκε."; sleep(2000); menu();} 
        else {cout << "Η εισαγωγή δεν ολοκληρώθηκε."; sleep(2000); NewDoc();}
    }
    
    void menu() {
        int sel;
        system("clear");
        do {
            cout << "Μενού επιλογών:\n" << endl;
            cout << "1. Εισαγωγή γιατρού\n2. Εισαγωγή ασθενή\n\n3. Εισαγωγή ραντεβού\n4. Εμφάνιση υπαρχόντων ραντεβού\n\n5. Τερματισμός\n\n\nΕπιλογή:     ";
            cin >> sel;
        } while (sel < 1 || sel > 5);
        
        switch(sel) {
            case 1: NewDoc(); break;
            case 2:break;
            case 3:break;
            case 4:break;
            case 5:break;
        }
    }    
    
    main() {
        
        int i; for(i=0; i<100; i++) {Doctors[i]=NULL;} //Αρχικοποίηση πίνακα δεικτών
        menu();
    }


    Όπως βλέπεις, στην main αρχικοποιώ τον πίνακα δεικτών Doctors. Με την λογική (; ) μου, την πρώτη φορά που θα έκανα εισαγωγή ονόματος, δεν θα έμπαινε σε κανέναν από τους δύο βρόχους while, καθώς όλοι οι δείκτες θα ήταν NULL.

    Όσο για την άτσαλη έξοδο από την NewDoc(), το ξέρω, άλλα έκανα αρχικά ένα πρόχειρο πρόγραμμα και σε αργότερο στάδιο φυσικα και θα το άλλαζα. Εκτός αν υπάρχει ενδεχόμενο να φταίει κι αυτό για την cin που δεν λειτουργεί.

    Εννοείται ότι σε ευχαριστώ πολύ που ασχολήθηκες με το πρόβλημα μου
    Τελευταία επεξεργασία από το μέλος Simpleton : 30-06-08 στις 18:12.
    - Κάνετε τη δουλειά σας γρήγορα, αξιόπιστα, με ασφάλεια, χωρίς τεχνητούς περιορισμούς και δωρεάν με το Linux.
    - Οι δίσκοι χαλάνε! Σκεφτείτε τα αρχεία σας πριν την πατήσετε. Κάνετε τακτικά backup.

  6. #6
    Το avatar του μέλους turboirc
    turboirc Guest
    Συγγνώμη, αλλα γιατι δεν το περνάς από τον debugger για να σου πει ακριβώς το πρόβλημα?

    *Doctors[100]

    Μήπως εννοούσες χωρίς το * ?

  7. #7
    Εγγραφή
    21-03-2008
    Ηλικία
    36
    Μηνύματα
    9.890
    Downloads
    8
    Uploads
    2
    Τύπος
    VDSL2
    Ταχύτητα
    51200/5120
    ISP
    Nova
    Router
    VMG8623-T50B & Debian
    Παράθεση Αρχικό μήνυμα από turboirc Εμφάνιση μηνυμάτων
    Συγγνώμη, αλλα γιατι δεν το περνάς από τον debugger για να σου πει ακριβώς το πρόβλημα?
    Δεν ξέρω ακόμα να τον χειρίζομαι

    Παράθεση Αρχικό μήνυμα από turboirc Εμφάνιση μηνυμάτων
    *Doctors[100]

    Μήπως εννοούσες χωρίς το * ?
    Για να μην δεσμεύω εξαρχής χώρο για 100 αντικείμενα Doc, ήθελα να δηλώσω έναν πίνακα 100 θέσεων με δείκτες προς αντικείμενα Doc. Λάθος είναι;
    - Κάνετε τη δουλειά σας γρήγορα, αξιόπιστα, με ασφάλεια, χωρίς τεχνητούς περιορισμούς και δωρεάν με το Linux.
    - Οι δίσκοι χαλάνε! Σκεφτείτε τα αρχεία σας πριν την πατήσετε. Κάνετε τακτικά backup.

  8. #8
    Εγγραφή
    17-09-2007
    Ηλικία
    47
    Μηνύματα
    865
    Downloads
    1
    Uploads
    0
    skaf αυτό που έστειλες μου δουλεύει, με μια μετατροπή: το όρισμα της sleep() είναι σε δευτερόλεπτα, οπότε το 2000 είναι κανα 40λεπτο

    Κάντο σκέτο 2 για 2 δευτερόπλεπτα που μάλλον θές...

    Πάντως segfault δεν κάνει με 2 εισαγωγές.

  9. #9
    Το avatar του μέλους turboirc
    turboirc Guest
    1. Το βασικότερο είναι να χειρίζεσαι το debugger. Το debugging είναι στα πρωτα 10 βήματα στον προγραμματισμό και ειδικά σε ένα δύσκολο περιβάλλον σαν το Linux. Κάτσε και ψάξε ολα τα κόλπα που έχει ο debugger σου, το εννοώ όταν λέω όλα.

    2. Οχι δεν είναι λάθος, αλλά σήμερα τέτοιας μορφής κώδικας θεωρείται επικίνδυνος και απαρχαιωμένος. Καλύτερα να χρησιμοποιήσεις std::vector. Εαν ακόμα δεν ξέρεις από STL, διάβασε και χρησιμοποίησέ τη.

    3. Ο κώδικάς σου στα Windows δεν crasharei και επομένως δεν μπορώ να σε βοηθήσω περισσότερο από τον debugger σου. Γενικά πάντως ο G++ , ενώ είναι καλός C compiler, δεν είναι αξιόπιστος C++ compiler.

  10. #10
    Εγγραφή
    21-03-2008
    Ηλικία
    36
    Μηνύματα
    9.890
    Downloads
    8
    Uploads
    2
    Τύπος
    VDSL2
    Ταχύτητα
    51200/5120
    ISP
    Nova
    Router
    VMG8623-T50B & Debian
    ΟΚ, το γεγονός ότι δεν κρασάρει σε άλλη πλατφόρμα είναι πολύ θετικό. Οπότε έχει τώρα να πέσει γερό διάβασμα για debugging και STL...

    Ευχαριστώ και πάλι όλους που ασχοληθήκατε με την περίπτωση μου
    - Κάνετε τη δουλειά σας γρήγορα, αξιόπιστα, με ασφάλεια, χωρίς τεχνητούς περιορισμούς και δωρεάν με το Linux.
    - Οι δίσκοι χαλάνε! Σκεφτείτε τα αρχεία σας πριν την πατήσετε. Κάνετε τακτικά backup.

  11. #11
    Το avatar του μέλους turboirc
    turboirc Guest
    Καθόλου θετικό δεν είναι.
    Δείχνει οτι ο compiler έχει πρόβλημα.

    Αντιθέτως αμα κράσαρε και στα Windows θα σου λέγαμε και τον λόγο.
    Και μια τελευταία συμβουλή. Υποψιαζομαι οτι τον κωδικα αυτόν δεν τον έγραψες εσύ ολόκληρο. Μην χρησιμοποιείς κώδικα άλλου χωρίς να έχεις μάθει τη γλώσσα τέλεια.
    Τελευταία επεξεργασία από το μέλος turboirc : 30-06-08 στις 21:38.

  12. #12
    Εγγραφή
    21-03-2008
    Ηλικία
    36
    Μηνύματα
    9.890
    Downloads
    8
    Uploads
    2
    Τύπος
    VDSL2
    Ταχύτητα
    51200/5120
    ISP
    Nova
    Router
    VMG8623-T50B & Debian
    Παράθεση Αρχικό μήνυμα από turboirc Εμφάνιση μηνυμάτων
    Καθόλου θετικό δεν είναι.
    Δείχνει οτι ο compiler έχει πρόβλημα.

    Αντιθέτως αμα κράσαρε και στα Windows θα σου λέγαμε και τον λόγο.
    Και μια τελευταία συμβουλή. Υποψιαζομαι οτι τον κωδικα αυτόν δεν τον έγραψες εσύ ολόκληρο. Μην χρησιμοποιείς κώδικα άλλου χωρίς να έχεις μάθει τη γλώσσα τέλεια.
    Ο compiler μπορεί να έχει πρόβλημα, αλλά το ότι δούλεψε σε εσάς σημαίνει ότι τουλάχιστον δεν έφταιγε ο κώδικας. Τελικά τον κατάφερα και δούλεψε και στο δικό μου σύστημα.

    Ο κώδικας που παρέθεσα είναι όλος δικός μου.
    - Κάνετε τη δουλειά σας γρήγορα, αξιόπιστα, με ασφάλεια, χωρίς τεχνητούς περιορισμούς και δωρεάν με το Linux.
    - Οι δίσκοι χαλάνε! Σκεφτείτε τα αρχεία σας πριν την πατήσετε. Κάνετε τακτικά backup.

  13. #13
    Το avatar του μέλους turboirc
    turboirc Guest
    Σε αυτήν την περίπτωση έχεις προχωρήσει πολύ σε ασκήσεις, πιο γρήγορα από ότι έπρεπε.
    Συνεχισε το διάβασμα και, κατα την γνώμη μου, δούλεψε με το Visual Studio.

Παρόμοια Θέματα

  1. Segmentation fault σε C pointers
    Από artem στο φόρουμ Προγραμματισμός και γλώσσες προγραμματισμού
    Μηνύματα: 11
    Τελευταίο Μήνυμα: 02-04-08, 23:38
  2. Mplayer segmentation fault
    Από adminis στο φόρουμ Unix - Linux
    Μηνύματα: 6
    Τελευταίο Μήνυμα: 07-05-06, 21:29
  3. Gentoo compilation -->Segmentation fault
    Από yiapap στο φόρουμ Unix - Linux
    Μηνύματα: 21
    Τελευταίο Μήνυμα: 06-02-06, 19:16
  4. gcc segmentation fault σε FreeBSD
    Από teacake στο φόρουμ Unix - Linux
    Μηνύματα: 2
    Τελευταίο Μήνυμα: 28-01-06, 12:48
  5. firefox segmentation fault
    Από Rama στο φόρουμ Windows
    Μηνύματα: 4
    Τελευταίο Μήνυμα: 25-12-05, 11:32

Tags για αυτό το Θέμα

Bookmarks

Bookmarks

Δικαιώματα - Επιλογές

  • Δεν μπορείτε να δημοσιεύσετε νέα θέματα
  • Δεν μπορείτε να δημοσιεύσετε νέα μηνύματα
  • Δεν μπορείτε να αναρτήσετε συνημμένα
  • Δεν μπορείτε να επεξεργαστείτε τα μηνύματα σας
  •  
  • Τα BB code είναι σε λειτουργία
  • Τα Smilies είναι σε λειτουργία
  • Το [IMG] είναι σε λειτουργία
  • Το [VIDEO] είναι σε λειτουργία
  • Το HTML είναι εκτός λειτουργίας