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

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

Δημοσ.

Καλημέρα,θα ηθελα να ρωτήσω το εξής

στο πρόγραμμα που αναπτύσω χρειάζεται να επιστρέφω διανύσματα(ισως και διαστάσεων >1,διδιαστατους πινακες πολλεσ φορές) μέσα 

απο κατάλληλες συναρτήσεις.

 

Έχω υλοποιήσει το 2-διαστατο πινακα χρησιμοποιώντας το deque container απο την stl

σαν deque<deque<myType> > x

 

Ποιος είναι ο πιο αποδοτικός τρόπος (απο αποψη μνήμης) να επιστρέφω το διάνυσμα (καποιο deque object)

 

Νομίζω οι pointers δεν βολεύουν ιδιαίτερα ειδικά οταν έχεις ν - διάσταστους πίνακες.

Στην ουσία θέλω κάποιος πίνακας που επιστρέφεται απο μία συνάρτηση 

να περνίεται σαν παράμετρος σε μία άλλη στην οποία θα γίνεται περαιτέρω επεξεργασία

 

και θέλω ο τρόπος επιστροφής να είναι τέτοιος ώστε οι τελεστές [] να μπορούν να δουλευουν 

σωστά(κάτι το οποίο δεν γίνεται σε περίπτωση που επιλέξω να επιστρέφω iterator).

 

Δημοσ.

reference

Εισαι σίγουρος ότι δουλεύει? ηταν το πρώτο που δοκίμασα

 

πχ

deque< deque<myType> >& myFunction1()

{

....

deque< deque <myType> > x;

......

deque<myType> temp;

...

....

temp.push_back(t1);

temp.push_back(t2);

....

x.push_back(temp);

....

return x;

}

 

 

void function2(deque<deque <myType>> &z)

{

   for(unsigned int i=0;i<z.size();i++)

        for(unsigned int j=0;j<z.size();j++)

            {

               .... Do computations ..z[j]*a ....

            }

 

}

Δημοσ.

Στην function2 περνάς pointer, όχι reference. Reference θα ήταν έτσι: deque<deque <myType>>& z.

Δε νομίζω πως έχει διαφορά το deque<deque <myType>>& z απ το deque<deque <myType>> &z.

 

 

deque< deque<myType> >& myFunction1()

{

deque< deque <myType> > x;

...

return x;

}

Αυτό είναι σίγουρα λάθος (δε ξέρω αν βγάζει και warnings ή αν γίνεται compile)

Γιατί φτιάχνεις ένα αντικείμενο στη stack, που ζει δηλαδή μόνο μέσα σε αυτή τη συνάρτηση και περνάς την αναφορά του (τη διεύθυνση μνήμης του κατ ουσίαν) έξω απο αυτή.

 

Μόνο που όταν αυτή τελειώσει το αντικείμενο αυτό θα "πεθάνει". Άρα η αναφορά που θα επιστρέψει θα δείχνει τυχαία σε μία θέση μνήμης που δε θα είναι δεσμευμένη καν.

 

-

 

Τώρα, το τι είναι αποδοτικό από άποψη μνήμης είναι μια μεγάλη συζήτηση.

Καθαρά (και στενόμυαλα) μιλώντας αυτό που "τρώει" τη λιγότερη μνήμη είναι να φτιάχνεις όλα τα αντικείμενα στη heap και να δουλεύεις με τους ponters αυτών.

 

Ωστόσο κάτι τέτοιο αν δεν έχεις προσέξει πάρα^10 πολύ θα οδηγεί σε memory leaks οπότε και πάλι ασύμφορο είναι για τη "μνήμη".

 

Γενικά εξαρτάται από το τι συνολικά θέλεις να κάνεις. Από το συνολικό σχεδιασμό που έχουν τα αντικείμενά σου. Δε νομίζω ότι υπάρχει μια απάντηση και μόνο σε αυτό που ρωτάς.

 

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

  • Moderators
Δημοσ.

Δε νομίζω πως έχει διαφορά το deque<deque <myType>>& z απ το deque<deque <myType>> &z.

 

Απ' ό,τι ξέρω το & ακριβώς μετά τον τύπο δηλώνει reference, ενώ ακριβώς πριν από τη μεταβλητή δηλώνει τη διεύθυνσή της.

Δημοσ.

Καλημέρα,θα ηθελα να ρωτήσω το εξής

στο πρόγραμμα που αναπτύσω χρειάζεται να επιστρέφω διανύσματα(ισως και διαστάσεων >1,διδιαστατους πινακες πολλεσ φορές) μέσα 

απο κατάλληλες συναρτήσεις.

 

Έχω υλοποιήσει το 2-διαστατο πινακα χρησιμοποιώντας το deque container απο την stl

σαν deque<deque<myType> > x

 

Ποιος είναι ο πιο αποδοτικός τρόπος (απο αποψη μνήμης) να επιστρέφω το διάνυσμα (καποιο deque object)

 

Νομίζω οι pointers δεν βολεύουν ιδιαίτερα ειδικά οταν έχεις ν - διάσταστους πίνακες.

Στην ουσία θέλω κάποιος πίνακας που επιστρέφεται απο μία συνάρτηση 

να περνίεται σαν παράμετρος σε μία άλλη στην οποία θα γίνεται περαιτέρω επεξεργασία

 

και θέλω ο τρόπος επιστροφής να είναι τέτοιος ώστε οι τελεστές [] να μπορούν να δουλευουν 

σωστά(κάτι το οποίο δεν γίνεται σε περίπτωση που επιλέξω να επιστρέφω iterator).

 

Πρώτον, γιατί deque και όχι vector? Το λέει και τ' όνομα δηλαδή.

 

Από άποψη μνήμης όλοι οι σωστοί τρόποι είναι εξίσου αποδοτικοί: κάπου υπάρχει ένα και μόνο ένα αντίγραφο του διανύσματός σου. Θα πρέπει να το κάνεις επίτηδες για να υπάρξει και δεύτερο. Ανάλογα το πώς επιστρέφεις την τιμή και πού την αποθηκεύεις και άλλα βουντού υπάρχει περίπωση να γίνεται προσωρινά έξτρα αντίγραφο το οποίο κοστίζει σε χρόνο και (προσωρινά) σε μνήμη, αλλά αυτό εξαρτάται από πολλούς παράγοντες και δε γίνεται να σου δώσουμε απάντηση βλέποντας μόνο τη function σου.

 

Αυτό που λες με τους pointers δεν είναι ξεκάθαρο τι εννοείς.

 

Το να επιστρέψεις iterator έχει εν δυνάμει πολύ διαφορετικά αποτελέσματα από το να επιστρέψεις κάτι άλλο, οπότε το θέμα είναι πολύ σοβαρότερο από το αν απλά μετά βολεύεσαι να χρησιμοποιήσεις [].

 

Απλά επέστρεψε το x και άσε τα references. Αν σ' ενδιαφέρει να μάθεις περισσότερα και χρησιμοποιείς C++11, διάβασε για rvalue references και move constructors. Τυχαίο result από google.

 

reference

 

Θέλεις βούρδουλα. Τα references δεν είναι το μαγικό ραβδί του red bull και η απάντηση αυτή πέρα του ότι δε μπορεί να είναι σωστή όντας μονολεκτική, δεν είναι σωστή και γενικότερα. Γιατί δηλαδή το να επιστρέψει reference είναι πιο γρήγορο ντε και καλά;

 

 

Μόνο που όταν αυτή τελειώσει το αντικείμενο αυτό θα "πεθάνει". Άρα η αναφορά που θα επιστρέψει θα δείχνει τυχαία σε μία θέση μνήμης που δε θα είναι δεσμευμένη καν.

 

Γενικά εξαρτάται από το τι συνολικά θέλεις να κάνεις. Από το συνολικό σχεδιασμό που έχουν τα αντικείμενά σου. Δε νομίζω ότι υπάρχει μια απάντηση και μόνο σε αυτό που ρωτάς.

 

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

 

Σωστός, απλά συμπληρώνω ότι θα μπορούσε να επιστρέφει const X  & στην οποία περίπτωση το lifetime του temporary αυξάνεται όσο χρειαστεί για να γίνει ίσο με το lifetime του reference. It is known.

 

Απ' ό,τι ξέρω το & ακριβώς μετά τον τύπο δηλώνει reference, ενώ ακριβώς πριν από τη μεταβλητή δηλώνει τη διεύθυνσή της.

To & δηλώνει reference όταν χρησιμοποιείται σα μέρος ενός declaration, όπως εδώ. Το πριν/μετά είναι μπακαλιά η οποία οδηγεί σε λάθη.

  • Like 1
Δημοσ.

 

Defacer:

Σωστός, απλά συμπληρώνω ότι θα μπορούσε να επιστρέφει const X  & στην οποία περίπτωση το lifetime του temporary αυξάνεται όσο χρειαστεί για να γίνει ίσο με το lifetime του reference. It is known.

 

 

@Defacer: Εννοείς κάτι τέτοιο; 

class X {...};

const X& foo() 
{
    X some_x;
    ...;
    return some_x;
}

const X &val = foo(); 
Δημοσ. (επεξεργασμένο)

Αν χρησιμοποιείς c++ κανε τα interfaces να είναι compatible με stl, θα σε βοηθήσει αργότερα.

template<typename InputIterator, typename OutputIterator>
void doSomething(InputIterator begin, InputIterator end, OutputIterator out){
  /// in your loop
  while( begin != end ){ 
      /// calculate something
      *out = something;
      out++;
      begin++;
  } 
}

You can use std::back_inserter in order to insert values to your container.

Or if you need to return a range, make your interfaces with iterators like:
class MyClass{
public:
 typedef typename std::vector< type >::const_iterator const_iterator;
 const_iterator begin()const{...}
 const_iterator end()const{...}
};
Επεξ/σία από m1cRo
  • Like 1
Δημοσ.

Τα iterator ειναι γλυκουλικα αλλά ταυτοχρονως τραγικα αργα σε σχεση με το array subscript operator.

 

btw, οταν εγραψα reference, ειχα στο μυαλο μου κατι σε στυλ pipeline.

Δημοσ.

 

@Defacer: Εννοείς κάτι τέτοιο; 

class X {...};

const X& foo() 
{
    X some_x;
    ...;
    return some_x;
}

const X &val = foo(); 

 

Όχι, και τώρα που με ξαναδιαβάζω βλέπω ότι δεν το είπα καλά. Είχα στο μυαλό μου αυτό:

X foo()
{
    X some_x;
    ...;
    return some_x;
}

const X &val = foo();

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...