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

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • 0
Apanepai

Error μετά από λειτουργία προγράμματος γραμμένο σε C++

Ερώτηση

Καλησπέρα παιδιά. Για ακόμα μία φορά χρειάζομαι τη βοήθειά σας. Έχω γράψει ένα πρόγραμμα σε c++ το οποίο κατασκεύαζει ένα πίνακα με τυχαία στοιχεία μήκους δωσμένου από το χρήστη και τα ταξηνομεί. Το πρόγραμμα λειτουργεί μία χαρά. Όταν όμως δωθούν σαν αριθμός στοιχείων πάνω από 3 τότε μετά την εκτέλεση του προγράμματος μου επιστρέφουν σφάλμα τα xp λέγοντας ότι η εφαρμογή αντιμετώπισε πρόβλημα και πρέπει να τερματιστεί.

 

Πρόκειται για console application (MSDOS Window) και σαν compiler έχει χρησιμοποιηθεί ο Dev-C++.

 

Καμία ιδέα για το που μπορεί να είναι το πρόβλημα. Με συγχωρείται που δεν μπορώ να δώσω τον κώδικα ώστε να γίνει άμεση αναγνώριση του προβήματος εάν εντωπίζεται εκεί.

Για να δώσω μια γενική εικόνα έχει γίνει η χρήση μίας κλάσης με 3-4 συναρτήσεις για τις λειτουργίς και για τις επιστροφές των δεδομένων. Και φυσικα το array για το οποίο γίνεται λόγος.

 

Κάθε βοήθεια είναι πολύτιμη για εμάς τους αρχάριους ευχαριστώ.

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

13 απαντήσεις σε αυτή την ερώτηση

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

δεν ειπα "απο την αρχη", είπα "ην στιγμη που κάνεις allocation"

αυτο αυτοματα σου λεει πως δεν θα κανεις αλλοκεησιον οταν ξεκιναει το προγραμμα αλλα όταν θα σου πει ο χρηστης ποσα θέλει. Δηλαδη θα του πεις στην αρχη "ποσα θελετε? γραψτε το νουμερο και πατηστε ENTER", θα παρεις το ινπουτ του στη μεταβλητη len, θα κάνει allocation του πινακα με

>table = new int[len]; 

και μετα θα του πεις "ξεκινα να δινεις στοιχεια χρηστη..."

 

για τη περιπτωση του vector, κανε include το vector.h και τη μεταβλητη δηλωσε την ως

>std::vector<int> table; 

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
Σε ευχαριστώ για την βοήθεια τώρα πλεον τα πράγματα είναι ποιο ξεκάθαρα. Με θερισαν αυτοι οι δεικτές (που σε ρε java εργαλειο).

 

Και η υλοποιήση έγινε τελικά σωστά με χρήση διανύσματος απλός επειδή έλεγε ότι είναι στην standar βιβλιοθήκη δεν μου περασε απο το μυαλό ότι θέλει να κάνεις include και άλλο header.

 

Χρειάζεται καταστορφή το vector μετά τη χρήση για να ελευθερωθεί μνήμη?

 

Εξαρτάται, αν έχεις δεσμεύσει εσύ μνήμη για αυτό ναι λοιπόν πρέπει να την αποδεσμεύσεις, το vector είναι ένα container που μεγαλώνει περίεργα και δεν το βλέπεις να μεγαλώνει. Έτσι είναι άλλο το μέγεθος του κάθε φορά και άλλη η χωρητικότητα, το μέγεθος είναι πάντα μικρότερο και το πολύ ίσο με την χωρητικότητα. Αν ξεπεραστεί η χωρητικότητα τότε το vector αυτόματα αυξάνει την χωρητικότητα του για να χωρέσει και άλλα στοιχεία. Με την reserve() συνάρτηση δεσμέυεις manually την χωρητικότητα που θέλεις να έχει ένα vector. Να ξέρεις πως το vector όπως έχει τους constructor του, έχει τον destructor του για να είσαι τυπικός.

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

ε ναι,

την στιγμη που κάνεις allocation του πίνακα, πρέπει να είναι γνωστό το μεγεθός του. Άρα έχεις δυο επιλογές

1. ζητάς από το χρήστη να σου επι εκεινη τη στιγμή πόσα δεδομένα σκοπεύει να δώσει και αφου σου πεί ΤΟΤΕ θα πείς

table = new int[len];

 

2. χρησιμοποιείς vector αντι για array

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Σε ευχαριστώ georgemarios νομίζω πως τη βρήκα την άκρη.

 

Αλλά αντιμετώπιζω κάτι άλλο που πάει να με τρελάνει ενώ είναι πολύ απλό.

Στον παρακάτω κώδικα:

 

>#include <cstdlib>
#include <iostream>

using namespace std;

bool sortCheck (int table[])
            {
               bool sorted=true;
               for(int i=1; i<(sizeof(table)/sizeof(int)); i++)
               {
                cout<<i<<endl;
                if(table[i-1]>table[i])
                {
                 sorted=false;
                 break;
                 }
               }
               return sorted;
            }

int main(int argc, char *argv[])
{
   int table[]={6,2,3};
   cout<<sortCheck(table);
   system("PAUSE");
   return EXIT_SUCCESS;
}

 

διαπιστώνω από την εντολή εμφάνισης που έχω μέσα στο for loop ότι δεν μπαίνει καθόλου και δεν μπορώ να καταλάβω το λόγο. Και φυσικά στη main εμφανίζει πάντα ένα. Η λειτουργία που θέλω να υλοποιήσω είναι ο έλεγχος εαν ένας πίνακας είναι ταξινομημένος.

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Έχω ένα folder με φωτογραφίες. Μπορείς να μου πεις αν σε καποια από αυτές εικονίζεται η θεία μου η Μελπομένη και αν είναι τραβηγμένη πριν ή μετά το γάμο της?

 

Με συγχωρείται που δεν μπορώ να δώσω τις φωτογραφίες ώστε να γίνει άμεση αναγνώριση εάν φαίνεται εκεί.

 

Για να δώσω μια γενική εικόνα οι φωτογραφίες είναι έγχρωμες και η θεία μου φτιάχνει ωραίο μουσακά.

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

ναι γιατι εδω

>bool checkSorted(int table[])

δίνεις σαν όρισμα ουσιαστικά ενα ποιντερ σε integer. Αυτό έχει μέγεθος 4 (σε 32bit-α συστήματα) αλλα αυτό που έχει σημασία είναι ότι έχει μέθος ενος integer.

Αρα sizeof(table) == sizeof(int)

Αρα αυτο

>for(int i=1; i<sizeof(table)/sizeof(int); i++)

ισοδυναμεί με αυτο

>for(int i=1; i<1; i++)

που δεν θα εκτελεστεί καμία φορά (μη με ρωτας γιατι σε εκληπαρω)

 

Ο σωστός τρόπος είναι να ορίσεις την sortCheck ως εξής

>bool sortCheck(int *table, int numberOfStoixeia )

όπου numberOfStoixeia θα είναι ο αριθμός των στοιχείων του πίνακα το οποίο θα χρησιμοποιήσεις στο for-loop σου

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Ειναι κλασσικο προβλημα με την C++, πολυ απλα γραφεις εκτος των boundaries του array και κρασαρει ;-) Πρεπει να κανεις καποιο boundary check πριν γραψεις στο array

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Σε ευχαριστώ για την βοήθεια τώρα πλεον τα πράγματα είναι ποιο ξεκάθαρα. Με θερισαν αυτοι οι δεικτές (που σε ρε java εργαλειο).

 

Και η υλοποιήση έγινε τελικά σωστά με χρήση διανύσματος απλός επειδή έλεγε ότι είναι στην standar βιβλιοθήκη δεν μου περασε απο το μυαλό ότι θέλει να κάνεις include και άλλο header.

 

Χρειάζεται καταστορφή το vector μετά τη χρήση για να ελευθερωθεί μνήμη?

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Ορίστε ο κώδικας που γεμίζει το array με τυχαίους αριθμούς.

 

>srand( (unsigned)time(NULL) );
for(int i=0; i<len; i++)
  {
     table[i]=(rand()%100)+1;
     cout<<i<<"::\t"<<table[i]<<endl;
  }

 

Δεν μπορώ να καταλάβω για ποιο λόγο μπορεί να βγει εκτός ορίων ο πίνακας καθότι τίποτα δεν μεταβάλεται από το χρήστη. Ο πίνακας έχει δηλωθεί στα private δεδομένα της κλάσης και έπειτα έχω μια συνάρτηση η οποία κάνει set το όριο του πίνακα.

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

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

 

Τώρα όσον αφορά τη χρήση διανύσματος χρειάζεται λίγο σπρώξιμο γιατί δεν το έχω χρησιμοποιήσει ποτέ. Μέσα στα δεδομένα της κλάσης πάω να ορίσω και το διάνυσμα αλλά μου χτυπάει ο compiler λέγοντας

> ISO C++ forbids declaration of `vector' with no type 

 

>class Array{
     private:
             int len;     //arithmos stoixeiwn tou pinaka
             bool sorted; //metabliti elegxou taksinomisis
             vector<int> table(1);
     public:

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Παιδιά εντόπισα τελικά το πρόβλημα αλλά θέλω βοήθεια στη λύση του. Τον πίνακα τον αρχικοποιούσα ως εξής: int table[]

Πράγμα λάθος από ότι κατάλαβα. Χρειάζεται δυναμική παραχώρηση μνήμης με δήλωση του πίνακα ως εξής:

>int  *table = new int [len];

Το πρόβλημα είναι ότι για ευκολία στο πρόγραμμα θέλω να έχω στα private δεδομένα της κλάσης και το μήκος και το δυναμικό array. Αλλά όταν ορίζω τον πίνακα στα private δεδομένα μου χτυπάει ο compiler και λέει ότι

>Array::len' cannot appear in a constant-expression 

 

>class Array{
     private:
             int len;     //arithmos stoixeiwn tou pinaka
             bool sorted; //metabliti elegxou taksinomisis
             int  *table = new int [len]; 
     public:

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
Χρειάζεται καταστορφή το vector μετά τη χρήση για να ελευθερωθεί μνήμη?

 

το vector καθαυτο δε θέλει delete. Τα στοιχεία του είναι άλλη υπόθεση. Στη περιπτωση σου του βάζεις int στοιχεια, οχι, δε χρειάζεται τίποτε.

 

Με θερισαν αυτοι οι δεικτές (που σε ρε java εργαλειο)

 

ε γιαυτο φωναζουμε οι κακόμοιροι οτι αμα ξεκινησεις με ευκολες γλώσσες, που να μαθεις προγραμματισμο τελικα :devil::devil::devil:?

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
Εξαρτάται, αν έχεις δεσμεύσει εσύ μνήμη για αυτό ναι λοιπόν πρέπει να την αποδεσμεύσεις, το vector είναι ένα container που μεγαλώνει περίεργα και δεν το βλέπεις να μεγαλώνει. Έτσι είναι άλλο το μέγεθος του κάθε φορά και άλλη η χωρητικότητα, το μέγεθος είναι πάντα μικρότερο και το πολύ ίσο με την χωρητικότητα. Αν ξεπεραστεί η χωρητικότητα τότε το vector αυτόματα αυξάνει την χωρητικότητα του για να χωρέσει και άλλα στοιχεία. Με την reserve() συνάρτηση δεσμέυεις manually την χωρητικότητα που θέλεις να έχει ένα vector. Να ξέρεις πως το vector όπως έχει τους constructor του, έχει τον destructor του για να είσαι τυπικός.

 

Οκ σε ευχαριστώ για τις πληροφορίες.

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
×
×
  • Δημιουργία νέου...