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

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

Δημοσ.

Καλησπέρα! Έχουμε τον παρακάτω κώδικα που μας ζητάει 3 αριθμούς και μετά υπολογίζει και εμφανίζει το άθροισμα τους.

H vector_init(Vector& v, int s) όπως μπορείτε να δείτε χρησιμοποιεί το new για να κατανείμει χώρο μνήμης για ένα array με s σε πλήθος doubles που θα αποθηκευτούν οι αριθμοί.

Πως και που πρέπει να αποδεσμευτεί αυτός ο χώρος μνήμης;

Ευχαριστώ!

 

// tour22.cpp

#include <iostream>
using namespace std;

struct Vector {
    double* elem;   // pointer to elements
    int sz;         // number of elements
};

void vector_init(Vector& v, int s)  // initialize a Vector
{
    v.elem = new double[s];         // allocate an array of s doubles
    v.sz = s;
}

double read_and_sum(int s)          // read s integers from cin and return their sum; s is assumed to be positive
{
    Vector v;
    vector_init(v, s);              // allocate s elements for v
    for (int i = 0; i != s; ++i)
        cin >> v.elem[i];           // read into elements
    double sum = 0;
    for (int i = 0; i != s; ++i)
        sum += v.elem[i];           // compute the sum of the elements
    return sum;
}

int main(void)
{
    double sum = 0;
    
    cout << "Enter 3 numbers:\n";
    sum = read_and_sum(3);
    cout << "Sum: " << sum << '\n';
    return 0;
}

 

  • Moderators
  • Λύση
Δημοσ.

Δεν ξέρω πού θα μπορούσες να το βάλεις στο συγκεκριμένο κώδικα ούτως ώστε:

  1. να διασφαλιστείς από πιθανά προβλήματα
  2. να δουλεύει η εφαρμογή σου
  3. να βγάζει νόημα

Ενδεχομένως θα μπορούσες να το βάλεις στο read_and_sum, μιας και το function έχει ήδη side effects, οπότε θα μπορούσες να το "σώσεις" όπως μπορείς. Βέβαια, σε περίπτωση που έχεις exception πριν φτάσεις στο delete, τότε πιθανότατα θα έχεις leak.

Από κει και πέρα, αυτό που θα μπορούσες να κάνεις είναι να σπάσεις το read_and_sum σε 3 κομμάτια: το ένα κομμάτι το έχεις ήδη, είναι η αρχικοποίηση του πίνακα. Το δεύτερο είναι το διάβασμα του input από το χρήστη, και το 3ο είναι ο υπολογισμός του αθροίσματος. Έτσι, θα μπορούσες να έχεις τα παρακάτω στη main σου:

  1. αρχικοποίηση πίνακα
  2. διάβασμα αριθμών
  3. υπολογισμός αθροίσματος
  4. αποδέσμευση της μνήμης

Τώρα, αν θες να το πας ένα βήμα παραπέρα, μπορείς να δεις και τα εξής:

  1. Χρήση smart pointers. Ο μόνος λόγος (ίσως) να χρησιμοποιείς raw pointers είναι μόνο αν είναι non-owning. Οι owning raw pointers είναι ιδιαίτερα επικίνδυνοι (μπορεί να ξεχάσεις να τους ελευθερώσεις, προβλήματα null pointer dereferencing, exception safety κλπ κλπ).
  2. Να χρησιμοποιήσεις το std::vector (αν δεν ξέρεις το μέγεθος της λίστας σου) ή το std::array αν το ξέρεις.
  3. Αν θες σώνει και ντε το δικό σου class/struct, να βάλεις τη λειτουργικότητα του vector_init στον constructor του Vector (το οποίο ενδεχομένως και να μη χρειάζεται καν, αναλόγως της υλοποίησής σου)

Όλα τα παραπάνω με επιφύλαξη, καθώς έχω να χρησιμοποιήσω C++ αρκετά χρόνια οπότε μπορεί κάτι να μου έχει ξεφύγει ή να μην το θυμάμαι σωστά.

  • Like 1
Δημοσ.

Στο function read_and_sum(), δημιουργείς έναν πίνακα με doubles και αποθηκεύεις την διεύθυνσή του στο "v.elem". 

Πριν τελειώσει το function μπορείς να ελευθερώσεις τον πίνακα από το heap ως εξής: 

double read_and_sum(int s)          // read s integers from cin and return their sum; s is assumed to be positive
{
    Vector v;
    vector_init(v, s);              // allocate s elements for v
    for (int i = 0; i != s; ++i)
        cin >> v.elem[i];           // read into elements
    double sum = 0;
    for (int i = 0; i != s; ++i)
        sum += v.elem[i];           // compute the sum of the elements

    delete[] v.elem; 
    return sum;
}
  • Thanks 1
Δημοσ. (επεξεργασμένο)

Έχεις δίκιο, αυτό ζητούσα.

Ο χαζός δοκίμαζα σκέτο "delete[] v; και δεν μου το δεχόταν ο μεταγλωττιστής.

Σε ευχαριστώ!

Επεξ/σία από cvb~
Δημοσ.

Απο την ωρα που εχεις vector_init το οποιο κανει την δουλεια του allocator, δε μπορεις να βαλεις delete[]. Πρεπει να φτιαξεις δικο σου deallocator, τυπου vector_destroy/vector_release/vector_delete whateva.

  • Like 1

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

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

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

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

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

Σύνδεση

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

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