SlideShare a Scribd company logo
H ΓΛΩΣΣΑ C++
Μάθημα 3:
Κλάσεις και Δείκτες
Δημήτρης Ψούνης
Περιεχόμενα Μαθήματος
Α. Θεωρία
1. Διαχείριση Μνήμης
1. Στατική Δέσμευση Μνήμης
2. Στατική Δέσμευση Μνήμης για
Συνήθεις Μεταβλητές
3. Στατική Δέσμευση Μνήμης για
Αντικείμενα
2. Δυναμική Δέσμευση Μνήμης
1. Δείκτες (Υπενθύμιση από C)
2. Οι τελεστές new και delete
3. Δυναμική Δέσμευση για Συνήθεις
Μεταβλητές
4. Δυναμική Δέσμευση για Αντικείμενα
5. Δυναμική Δέσμευση και
Κατασκευαστές
2Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
3. Κλάσεις που περιέχουν δείκτες
1. Παράδειγμα κλάσης που περιέχει
δείκτες
2. …και ένα πρόβλημα (χωρίς λύση για
την ώρα)
4. Δυναμική Δέσμευση Μνήμης για
Πίνακες
1. Μονοδιάστατοι πίνακες
2. Παράδειγμα δέσμευσης μνήμης για
μονοδιάστατους πίνακες
3. Διδιάστατοι πίνακες
4. Παράδειγμα δέσμευσης μνήμης για
διδιάστατους πίνακες
B. Ασκήσεις
A. Θεωρία
1. Διαχείριση Μνήμης
1. Στατική και Δυναμική Δέσμευση Μνήμης
3Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
• Η διαχείριση μνήμης στη C++ γίνεται με παρόμοιο τρόπο με τη C.
• Τα παρακάτω είναι εντελώς αντίστοιχα:
• Στατική Δέσμευση Μνήμης:
• Είναι γνωστός εκ των προτέρων ο χώρος μνήμης που απαιτείται για τα στιγμιότυπα.
• Και έχει ήδη αποφασιστεί κατά το χρόνο μεταγλώττισης (π.χ. δηλώνουμε έναν πίνακα 10
θέσεων)
• Οι τοπικές μεταβλητές αποθηκεύονται στον χώρο της συνάρτησης (στοίβα – stack)
• Δυναμική Δέσμευση Μνήμης:
• Δεν είναι γνωστός εκ των προτέρων ο χώρος μνήμης που πρέπει να δεσμεύσει το
πρόγραμμά μας.
• Αλλά αποφασίζεται κατά το χρόνο εκτέλεσης (π.χ. ο χρήστης αποφασίζει πόσες θέσεις θα
έχει ένας πίνακας που χρησιμοποιεί το πρόγραμμα)
• Ο χώρος μνήμης που δεσμεύεται δυναμικά είναι κοινός για όλες τις συναρτήσεις (σωρός –
heap)
A. Θεωρία
1. Διαχείριση Μνήμης
2. Στατική Δέσμευση μνήμης για συνήθεις μεταβλητές
4Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
/* CPP3.local_variables.cpp */
#include <iostream>
using namespace std;
void f()
{
int y=3;
cout<<"inside f";
}
int main()
{
int x=5;
cout<<"inside main";
f();
return 0;
}
• Κάθε συνάρτηση έχει το δικό της χώρο μνήμης.
• Κάθε τοπική μεταβλητή αποθηκεύεται στο χώρο μνήμης της
συνάρτησης στην οποία ανήκει.
• Σχηματικά, για το παράδειγμα:
• Αυτός ο χώρος μνήμης καλείται και στοίβα (stack), λόγω του
τρόπου με τον οποίο εχει υλοποιηθεί η κλήση των
συναρτήσεων σε μία στοίβα:
main
f
A. Θεωρία
1. Διαχείριση Μνήμης
3. Στατική Δέσμευση μνήμης για Αντικείμενα
5Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
• Ένα αντικείμενο αποθηκεύεται στη μνήμη ως εξής:
• Τα μέλη του βρίσκονται σε διαδοχικές θέσεις μνήμης
• Προσοχή, οι μέθοδοι βρίσκονται σε άλλο χώρο (είναι κοινές για όλα τα αντικείμενα της κλάσης)
• Ο τελεστής sizeof μπορεί να χρησιμοποιήθεί για να μετρήσουμε το πλήθος των bytes που
χρησιμοποιεί ένα αντικείμενο.
• Παράδειγμα:
/* CPP3.sizeof.cpp
Μέγεθος αντικειμένου */
#include <iostream>
using namespace std;
class dummy {
public:
int x;
int y;
};
int main()
{
dummy ob;
ob.x = 3; ob.y = 5;
cout<<sizeof ob<<endl;
return 0;
}
• Θα τυπώσει 8 (δύο ακέραιοι 4bytes ο
καθένας)
• Και η εικόνα της μνήμης:
A. Θεωρία
2. Δυναμική Δέσμευση Μνήμης
1. Δείκτες (Υπενθύμιση από C)
6Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
• Ένας δείκτης είναι μια μεταβλητή που αποθηκεύει διευθύνσεις μεταβλητών
• Ένας δείκτης δηλώνεται ως εξής:
• Όπου ΤΔ είναι ένας οποιοσδήποτε τύπος δεδομένων (int, float, double κ.λπ.)
• Π.χ. ένας δείκτης σε ακέραιο δηλώνεται με τη δήλωση:
• Αποθηκεύουμε σε έναν δείκτη την διεύθυνση μιας μεταβλητής με τη δήλωση:
• O τελεστής & επιστρέφει τη διεύθυνση της μεταβλητής στην οποία εφαρμόζεται.
• Π.χ. αποθηκεύουμε στον δείκτη ptr τη διεύθυνση μιας μεταβλητής x με την εντολή:
• και λέμε «ο δείκτης ptr δείχνει στην μεταβλητή x»
ΤΔ *pointer_name;
int *ptr;
pointer_name = &variable;
ptr = &x;
• Αναλυτικά βλ. και «Γλώσσα C – Μάθημα 8: Δείκτες»
A. Θεωρία
2. Δυναμική Δέσμευση Μνήμης
1. Δείκτες (Υπενθύμιση από C)
7Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
/* CPP3.pointers.cpp */
#include <iostream>
using namespace std;
int main()
{
int x=5;
int *p = NULL;
p = &x;
cout<<"x = "<<x<<" (address: "<<&x<<")"<<endl;
cout<<"*p = "<<*p<<" (address: "<<p<<")"<<endl;
return 0;
}
• Το πρόγραμμα δείχνει την βασική ιδιότητα:
• Για ένα δείκτη (p) που «δείχνει» σε μία
μεταβλητη ισχύουν:
• To NULL είναι μία ειδική τιμή
• που συμβολίζει ότι ο δείκτης δεν
δείχνει κάπου.
• Είναι καλό ένας δείκτης που δεν δείχνει
κάπου να έχει την τιμή NULL
• H τιμη του NULL είναι 0.
• Σχηματικά:
p == &x //Διεύθυνση της x
*p == x // Τιμή της x
A. Θεωρία
2. Δυναμική Δέσμευση Μνήμης
2. Οι τελεστές new και delete
8Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
• Ο τελεστής new χρησιμοποιείται για να δεσμεύσει δυναμικά χώρο μνήμης
• Αντικαθιστά τη malloc της C.
• Η σύνταξη του είναι:
• Δεσμεύει χώρο μνήμης για ένα αντικείμενου τύπου type και επιστρέφει έναν δείκτη σε
αυτόν το χώρο
• Ο χώρος μνήμης που δεσμεύεται δυναμικά, είναι κοινός για όλες τις συναρτήσεις και
ονομάζεται σωρός (heap)
• Προσοχή, αν αποτύχει η δέσμευση (δεν υπάρχει χώρος) επιστρέφει NULL
• και θα πρέπει πάντα να ελέγχουμε ότι η δέσμευση έγινε επιτυχημένα
ptr = new type;
• Ο τελεστής delete χρησιμοποιείται για να απόδεσμευσει χώρο μνήμης που έχει δεσμευτεί
δυναμικά
• Αντικαθιστά τη free της C.
• Η σύνταξη του είναι:
delete ptr;
A. Θεωρία
2. Δυναμική Δέσμευση Μνήμης
2. Οι τελεστές new και delete (Έλεγχος Δέσμευσης Μνήμης)
9Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
• Πάντα πρέπει να κάνουμε έλεγχο αν η μνήμη που αιτηθήκαμε με τη new, έχει όντως δεσμευτεί.
• Βλέπουμε τρεις τρόπους για να «πιάσουμε» το πρόβλημα:
• A’ τρόπος: Ο πιο απλός, μιας και απλά ελέγχουμε την επιστρεφόμενη τιμή:
• Β’ τρόπος: Πιο ψαγμένος, ξέρουμε ότι το NULL είναι 0 (και για να είμαστε ακριβής (void *) 0)
• Και ξέρουμε ότι το 0, είναι το λογικό ψευδές
• και το !0 είναι το λογικό αληθές:
• Γ’τρόπος: Ο πιο σύνθετος και φαντεζί, αλλά ενσωματώνει τις δύο εντολές σε μία γραμμή:
• Στις σημειώσεις θα χρησιμοποιήσουμε κυρίως το Β’ τρόπο
• Και θα βγάζουμε απλά ένα ενημερωτικό μήνυμα (αργότερα θα μπορούμε να κάνουμε και
περισσότερα πράγματα, με τις εξαιρέσεις της C++)
ptr = new type;
if (ptr==NULL)
{ …. do some action… }
ptr = new type;
if (!ptr)
{ …. do some action… }
if (!(ptr = new type))
{ …. do some action… }
A. Θεωρία
2. Δυναμική Δέσμευση Μνήμης
3. Δυναμική Δέσμευση για Συνήθεις Μεταβλητές
10Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
• Το παράδειγμα δείχνει τη δέσμευση
μνήμης για έναν ακέραιο αριθμό, τόσο
στατικά όσο και δυναμικά:
#include <iostream> // CPP3.dynamic_variable.cpp
using namespace std;
int main()
{
int x; // Μεταβλητή που δεσμέυει στατικό χώρο
int *p; // Δείκτης σε ακέραιο
p = new int; // Δυναμική δέσμευση μνήμης
if (!p) cout<<“Error allocating memory”;
/* Αναθέσεις τιμών */
x = 1;
*p = 5;
/* Εκτυπώσεις */
cout<<"x = "<<x<<" (address: "<<&x<<")"<<endl;
cout<<"*p = "<<*p<<" (address: "<<p<<")"<<endl;
delete p; // Αποδέσμευση μνήμης
return 0;
}
Υπενθυμίσεις από τη C:
• Η x δεσμεύει χώρο μνήμης μέσα στο χώρο
μνήμης της συνάρτησης
• Ο χώρος που δεσμεύεται δυναμικά μέσω
της p, είναι ένας ξεχωριστός χώρος, κοινός
για όλο το πρόγραμμα
• (λέγεται και σωρός – heap)
• Σχηματικά:
A. Θεωρία
2. Δυναμική Δέσμευση Μνήμης
4. Δυναμική Δέσμευση για Αντικείμενα
11Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
/* CPP3.dynamic_object.cpp Δυναμική Δέσμευση
μνήμης για αντικείμενο */
#include <iostream>
using namespace std;
class dummy {
public:
int x;
};
int main()
{
dummy *p = NULL; //Θα δείξει σε αντικείμενο
p = new dummy; // Δέσμευση χώρου
if (!p) cout<<“Error allocating memory”;
/* Αναθέσεις τιμών */
p->x = 5;
/* Εκτυπώσεις */
cout<<"p->x = "<<p->x<<endl;
delete p; // Αποδέσμευση μνήμης
return 0;
}
• Αντίστοιχα (αφού μία κλάση είναι τύπος δεδομένων), μπορεί να δεσμευτεί δυναμικά χώρος
μνήμης για ένα αντικείμενο.
• Όταν χρησιμοποιούμε ένα αντικείμενο μέσω δείκτη,
• Έχουμε πρόσβαση στα δημόσια μέλη-μεθόδους μέσω του τελεστή -> (βελάκι)
• Βλέπουμε και ένα παράδειγμα:
A. Θεωρία
2. Δυναμική Δέσμευση Μνήμης
4. Δυναμική Δέσμευση για Αντικείμενα
12Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
/* CPP3.dereferencing.cpp */
#include <iostream>
using namespace std;
class dummy {
public:
int x;
};
int main()
{
dummy *p = NULL; //Θα δείξει σε αντικείμενο
p = new dummy; // Δέσμευση χώρου
if (!p) cout<<“Error allocating memory”;
/* Αναθέσεις τιμών */
(*p).x = 5;
/* Εκτυπώσεις */
cout<<"(*p).x = "<<(*p).x<<endl;
delete p; // Αποδέσμευση μνήμης
return 0;
}
• Δεδομένου ενός δείκτη που δείχνει σε ένα αντικείμενο.
• Με τον τελεστή *, έχουμε πρόσβαση στο ίδιο το αντικείμενο (dereferencing)
• Και ισχύει ότι το (*p) είναι το αντικείμενο στο οποίο δείχνει ο δείκτης.
• Συνεπώς έχουμε πρόσβαση στα δημόσια μέλη του (*p) με τον τελεστή . (τελεία)
• Βλέπουμε και ένα παράδειγμα:
A. Θεωρία
2. Δυναμική Δέσμευση Μνήμης
4. Δυναμική Δέσμευση για Αντικείμενα
13Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
/* CPP3.pointers_and_objects.cpp Δείκτης σε
αντικείμενο */
#include <iostream>
using namespace std;
class dummy {
public:
int x;
};
int main()
{
dummy ob;
dummy *p = &ob;
if (!p) cout<<“Error allocating memory”;
/* Αναθέσεις τιμών */
ob.x = 6;
/* Εκτυπώσεις */
cout<<ob.x<<" "<<p->x<<" "<<(*p).x<<endl;
return 0;
}
• Και ένα ακόμη παράδειγμα, όπου βάζουμε ένα δείκτη να δείχνει σε ένα ήδη υφιστάμενο
αντικείμενο:
• Για να τονιστεί η διαφορά στην πρόσβαση,
• απευθείας από το αντικείμενο (τελεστής .)
• μέσω δείκτη (τελεστής ->)
• μέσω dereferencing ( * και . )
A. Θεωρία
2. Δυναμική Δέσμευση Μνήμης
5. Δυναμική Δέσμευση και κατασκευαστές
14Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
• Όταν δημιουργούμε ένα αντικείμενο με τον τελεστή new,
• και εφόσον το αντικείμενο αυτό έχει κατασκευαστή
• πρέπει να περάσουμε και τα ορίσματα στον κατασκευαστή
• Ο κατασκευαστής καλείται όταν κάνουμε new
• Ο καταστροφέας καλείται όταν κάνουμε delete
/*
CPP3.constructor_destru
ctor.cpp */
#include <iostream>
using namespace std;
class dummy {
public:
dummy(int in_x);
~dummy();
private:
int x;
};
int main()
{
dummy *p = NULL;
p = new dummy(5); //constructing
if (!p) cout<<“Error allocating
memory”;
delete p; //destructing
return 0;
}
dummy::dummy(int in_x)
{
x = in_x;
cout<<"Constructing...";
}
dummy::~dummy()
{
cout<<"Destructing...";
}
A. Θεωρία
3. Κλάσεις που περιέχουν δείκτες
1. Παράδειγμα κλάσης που περιέχει δείκτη
15Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
• Ένας δείκτης είναι απλά μία μεταβλητή
• Συνεπώς μπορεί να είναι μέλος σε κλάση
• Βλέπουμε ένα απλό παράδειγμα:
• Στο οποίο δεσμεύουμε δυναμικά στον κατασκευαστή το χώρο για έναν ακέραιο
• και τον αποδεσμεύουμε στον καταστροφέα.
/* CPP3.class_with_pointer */
#include <iostream>
using namespace std;
class dummy {
public:
dummy();
~dummy();
void set_val(int in_val);
int get_val();
private:
int *p_val;
};
A. Θεωρία
3. Κλάσεις που περιέχουν δείκτες
1. Παράδειγμα κλάσης που περιέχει δείκτη
16Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
int main()
{
dummy ob;
ob.set_val(3);
cout<<endl<<ob.get_val()<<endl;
return 0;
}
dummy::dummy()
{
p_val = new int;
if (!p_val) cout<<"Error allocating memory";
cout<<"Constructing...";
}
dummy::~dummy()
{
delete p_val;
cout<<"Destructing...";
}
void dummy::set_val(int in_val)
{
*p_val = in_val;
}
int dummy::get_val()
{
return *p_val;
}
A. Θεωρία
3. Κλάσεις που περιέχουν δείκτες
2. …και ένα πρόβλημα (χωρίς λύση για την ώρα)
17Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
• Ας δούμε και ένα πρόβλημα που μπορεί να προκύψει όταν μία κλάση περιέχει δείκτες που
κάνουν δυναμική διαχείριση μνήμης
• Το πρόβλημα αυτό προκύπτει όταν:
• Έχουμε μία κλάση που κάνει δυναμική δέσμευση μνήμης
• Κάνουμε αντιγραφή του αντικειμένου (π.χ. ob1 = ob2)
• Μεταγλωττίστε και εκτελέστε το ακόλουθο πρόγραμμα:
/* CPP3.assignment_problem Δυναμική Δέσμευση και Τελεστής Ανάθεσης */
#include <iostream>
using namespace std;
class dummy {
public:
dummy();
~dummy();
void set_val(int in_val);
int get_val();
private:
int *p_val;
};
A. Θεωρία
3. Κλάσεις που περιέχουν δείκτες
2. …και ένα πρόβλημα (χωρίς λύση για την ώρα)
18Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
int main()
{
dummy ob1;
ob1.set_val(3);
dummy ob2;
ob2 = ob1;
cout<<ob1.get_val()<<endl;
cout<<ob2.get_val()<<endl;
return 0;
}
dummy::dummy()
{
p_val = new int;
if (!p_val) cout<<"Error allocating memory";
cout<<"Constructing...";
}
dummy::~dummy()
{
delete p_val;
cout<<"Destructing...";
}
void dummy::set_val(int in_val)
{
*p_val = in_val;
}
int dummy::get_val()
{
return *p_val;
}
• Σημαντικό! Στη C++ οι μεταβλητές μπορούν να δηλωθούν σε οποιοδήποτε μέρος του
προγράμματος (αλλά θα το αποφεύγουμε…)
A. Θεωρία
3. Κλάσεις που περιέχουν δείκτες
2. …και ένα πρόβλημα (χωρίς λύση για την ώρα)
19Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
• H εκτέλεση του προγράμματος οδηγεί σε σφάλμα κατά το χρόνο εκτέλεσης:
• Για να καταλάβουμε γιατί συμβαίνει αυτό, θα δούμε την κατάσταση της μνήμης βήμα – βήμα
κατά την εκτέλεση της main
A. Θεωρία
3. Κλάσεις που περιέχουν δείκτες
2. …και ένα πρόβλημα (χωρίς λύση για την ώρα)
20Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
• dummy ob1; // Δεσμεύει το χώρο για το ob1.
• ob1.set_val(3); // αποθηκεύει την τιμή 3 στο χώρο μνήμης
A. Θεωρία
3. Κλάσεις που περιέχουν δείκτες
2. …και ένα πρόβλημα (χωρίς λύση για την ώρα)
21Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
• dummy ob2; // Δεσμεύει το χώρο για το ob2.
• ob2=ob1 // Δεν κάνει ακριβώς αυτό που θέλουμε…
A. Θεωρία
3. Κλάσεις που περιέχουν δείκτες
2. …και ένα πρόβλημα (χωρίς λύση για την ώρα)
22Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
• Τώρα με την ολοκλήρωση του προγράμματος, θα τρέξουν οι δύο destructors.
• Συνεπώς ο ίδιος χώρος μνήμης θα αποδεσμευτεί δύο φορές.
• Και αυτό οδηγεί σε σφάλμα στο χρόνο εκτέλεσης.
• Ενώ ισχύει ότι έχουμε κάνει και το βασικό λάθος
• Με την ολοκλήρωση του προγράμματος, έχει ξεμείνει χώρος μνήμης, τον οποίο
δεσμεύσαμε δυναμικά και δεν τον αποδεσμεύσαμε ποτέ (memory leak)
• Το πρόβλημα αυτό προκύπτει όταν γίνεται bit by bit αντιγραφή αντικειμένων (shallow copy)
• όπως στην περίπτωση που είδαμε,
• αλλά και σε άλλες περιπτώσεις (π.χ. όταν περνάμε ένα αντικείμενο μέσω τιμής σε μία
συνάρτηση)
• Θα αντιμετωπίσουμε το πρόβλημα αυτό, στα επόμενα μαθήματα:
• Θα μάθουμε τις αναφορές (references)
• και μέσω αυτών θα ορίσουμε τον κατασκευαστή αντιγράφου (copy constructor)
• επίσης θα μάθουμε την υπερφόρτωση του =
• και θα ορίσουμε τι πρέπει να γίνεται όταν έχουμε ανάθεση αντικειμένου
A. Θεωρία
4. Δυναμική Δέσμευση Μνήμης για Πίνακες
1. Μονοδιάστατοι Πίνακες
23Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
• Οι τελεστές new και delete χρησιμοποιούνται και για την δέσμευση μνήμης για πίνακες
• Δέσμευση Μνήμης:
• Η σύνταξη του τελεστή new είναι:
• Δεσμεύει χώρο μνήμης για n αντικείμενα τύπου type και επιστρέφει έναν δείκτη σε αυτόν
το χώρο
• Το n δεν χρειάζεται να είναι σταθερά.
• Αποδέσμευση Μνήμης:
• Η σύνταξη του τελεστή delete είναι:
ptr = new type [n];
delete [] ptr;
• Βλέπουμε και ένα παράδειγμα δέσμευσης μνήμης για έναν πίνακα n ακεραίων.
A. Θεωρία
4. Δυναμική Δέσμευση Μνήμης για Πίνακες
2. Παράδειγμα δέσμευσης μνήμης για μονοδιάστατο πίνακα
24Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
/* CPP3.1d_dynamic_array Μονοδιάστατος
πίνακας με δυναμική δέσμευση μνήμης */
#include <iostream>
using namespace std;
int main()
{
int *arr;
int n=4;
/* Δέσμευση Μνήμης */
arr = new int [n];
if (!arr) cout<<"Error allocating memory!";
/* Κάποια δουλειά στον πίνακα */
for (int i=0; i<n; i++)
arr[i]=i*i;
for (int i=0; i<n; i++)
cout<<arr[i]<<" ";
/* Αποδέσμευση Μνήμης */
delete [] arr;
return 0;
}
A. Θεωρία
4. Δυναμική Δέσμευση Μνήμης για Πίνακες
3. Διδιάστατοι Πίνακες
25Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
• Ένας διδιάστατος ΜxN πίνακας π.χ. ακεραίων είναι:
• ένας πίνακας M δεικτών σε ακέραιο
• όπου κάθε δείκτης είναι ένας πίνακας από N ακεραίους
• Σχηματικά (π.χ. για M=7, N=6):
1 5 2 4 3 2
6 4 6 9 3 4
2 5 9 4 6 2
1 8 9 6 2 3
9 1 5 1 6 7
9 8 4 1 3 5
1 9 7 6 4 2pin[6]
pin[1]
pin[2]
pin[3]
pin[4]
pin[5]
pin[0]
pin
pin[0][4]
pin[3][3]
pin[6][0]
M=7
γραμμές
Ν=6
στήλες
A. Θεωρία
4. Δυναμική Δέσμευση Μνήμης για Πίνακες
3. Διδιάστατοι Πίνακες
26Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
• Από τα παραπάνω:
• Η δέσμευση μνήμης θα γίνει με τις εντολές:
• Προσοχή, ότι το ptr είναι διπλός δείκτης
• αφου θέλουμε να δείχνει στην διεύθυνση μιας μεταβλητής που είναι διεύθυνση
ενός τύπου.
• Συνεπώς θα δηλωθεί ως:
• H αποδέσμευση θα γίνει εντολές:
ptr = new type * [Μ];
for (i=0; i<M; i++)
ptr[i] = new type [N];
type **ptr;
for (i=0; i<M; i++)
delete [] ptr[i];
delete [] ptr;
• Βλέπουμε και ένα παράδειγμα δέσμευσης μνήμης για έναν πίνακα n ακεραίων.
A. Θεωρία
4. Δυναμική Δέσμευση Μνήμης για Πίνακες
4. Παράδειγμα δέσμευσης μνήμης για διδιάστατο πίνακα
27Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
/* CPP3.2d_dynamic_array Διδιάστατος πίνακας με
δυναμική δέσμευση μνήμης */
#include <iostream>
using namespace std;
int main()
{
int **arr;
int i,j, n=3, m=5;
/* Δέσμευση Μνήμης */
arr = new int * [n];
if (!arr) cout<<"Error allocating memory!";
for (i=0; i<n; i++)
{
arr[i] = new int [m];
if (!arr[i]) cout<<"Error allocating memory!";
}
/* Κάποια δουλειά στον πίνακα */
for (i=0; i<n; i++)
for (j=0; j<m; j++)
arr[i][j]=i*j;
for (i=0; i<n; i++)
{
for (j=0; j<m; j++)
cout<<arr[i][j];
cout<<endl;
}
/* Αποδέσμευση Μνήμης */
for (i=0; i<n; i++)
delete [] arr[i];
delete [] arr;
return 0;
}
Β. Ασκήσεις
Άσκηση 1: Διπλοί Δείκτες
28Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
Για να πειραματιστούμε με τους δείκτες
• Δηλώστε μία ακέραια μεταβλητή x
• Τυπώστε την τιμή και τη διεύθυνσή της
• Δηλώστε έναν δείκτη σε ακέραιο p
• Θέστε τον να δείχνει στην x
• Τυπώστε την τιμή και τη διεύθυνση του
• Τυπώστε την τιμή του x, μέσω του p.
• Δηλώστε έναν δείκτη σε δείκτη σε ακέραιο, με όνομα pp
• Θέστε τον να δείχνει στον p
• Τυπώστε την τιμή και τη διεύθυνσή του
• Τυπώστε την τιμή του x, μέσω του pp.
• Τυπώστε την τιμή του p, μέσω του pp.
Β. Ασκήσεις
Άσκηση 2: Κλάση Δυναμικός Πίνακας
29Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες
Κατασκευάστε μία κλάση (ARRAY) που να περιτυλίσσει την έννοια του μονοδιάστατου πίνακα ως
εξής:
• Να έχει ως μέλη έναν δυναμικό πίνακα (δείκτης) ακεραίων, καθώς και τη διάσταση του πίνακα
• Ο κατασκευαστής να παίρνει ως όρισμα τη διάσταση του πίνακα και να δεσμεύει δυναμικά το
χώρο μνήμης που απαιτείται.
• Ο καταστροφέας να διαγράφει τη μνήμη που έχει δεσμευτεί δυναμικά.
• Να έχει accessors για ένα στοιχείο του πίνακα
• Να τυπώνουν μήνυμα λάθους, σε περίπτωση πρόσβασης εκτός των ορίων του πίνακα.
• Μία μέθοδο print που να τυπώνει τα στοιχείτα του πίνακα
Η συνάρτηση main
• Να κατασκευάζει έναν πίνακα της κλάσης με 10 θέσεις
• Να αρχικοποιεί τα στοιχεία του πίνακα, ώστε κάθε στοιχείο να έχει το τετράγωνο της
αντίστοιχης θέσης.
• Να τυπώνει τον πίνακα.
Ποιο πρόβλημα υπάρχει με την υλοποίηση; Πότε περιμένουμε ότι το πρόγραμμα αυτό θα έχει
πρόβλημα και θα «σκάσει» κατά το χρόνο εκτέλεσης;

More Related Content

PDF
Η ΓΛΩΣΣΑ C++ - ΜΑΘΗΜΑ 2 - ΕΙΣΑΓΩΓΗ ΣΤΙΣ ΚΛΑΣΕΙΣ
PDF
Η Γλώσσα C - Μάθημα 3
PDF
Η Γλώσσα C - Μάθημα 1
PDF
ΠΛΗ30 Τυπολόγιο Ενότητας 1
PPTX
Diabetes Mellitus
PPTX
Hypertension
PPTX
Republic Act No. 11313 Safe Spaces Act (Bawal Bastos Law).pptx
PPTX
Power Point Presentation on Artificial Intelligence
Η ΓΛΩΣΣΑ C++ - ΜΑΘΗΜΑ 2 - ΕΙΣΑΓΩΓΗ ΣΤΙΣ ΚΛΑΣΕΙΣ
Η Γλώσσα C - Μάθημα 3
Η Γλώσσα C - Μάθημα 1
ΠΛΗ30 Τυπολόγιο Ενότητας 1
Diabetes Mellitus
Hypertension
Republic Act No. 11313 Safe Spaces Act (Bawal Bastos Law).pptx
Power Point Presentation on Artificial Intelligence

What's hot (20)

PDF
Η ΓΛΩΣΣΑ C++ - ΜΑΘΗΜΑ 4 - ΚΛΑΣΕΙΣ ΚΑΙ ΑΝΑΦΟΡΕΣ
PDF
C++ - ΜΑΘΗΜΑ 1 - ΕΙΣΑΓΩΓΗ ΚΑΙ ΣΧΕΣΗ ΜΕ ΤΗ C
PDF
ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 9
PDF
ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 6 (ΕΚΤΥΠΩΣΗ)
PDF
ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 5 - ΔΟΜΕΣ ΕΠΑΝΑΛΗΨΗΣ
PDF
Η ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 15 - ΣΥΝΑΡΤΗΣΕΙΣ ΕΙΣΟΔΟΥ
PDF
ΑΛΓΟΡΙΘΜΟΙ ΣΕ C - ΜΑΘΗΜΑ 1 - ΔΙΑΠΕΡΑΣΗ ΠΙΝΑΚΑ
PDF
ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 18
PDF
Η Γλώσσα C - Μάθημα 2
PDF
ΠΛΗ10 ΜΑΘΗΜΑ 2.8
PDF
Η ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 7 - ΠΙΝΑΚΕΣ
PDF
Η ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 16 - ΣΥΝΑΡΤΗΣΕΙΣ ΕΞΟΔΟΥ (ΕΚΤΥΠΩΣΗ)
PDF
ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 10
PDF
Η ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 8 - ΔΕΙΚΤΕΣ
PDF
Η ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 14 - ΕΜΒΕΛΕΙΑ ΜΕΤΑΒΛΗΤΩΝ
PDF
ΑΛΓΟΡΙΘΜΟΙ ΣΕ C - ΜΑΘΗΜΑ 2 - ΑΝΑΖΗΤΗΣΗ ΣΤΟΙΧΕΙΟΥ ΣΕ ΠΙΝΑΚΑ
PDF
Η ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 12
PDF
ΠΛΗ10 ΜΑΘΗΜΑ 2.4
PDF
ΠΛΗ10 ΜΑΘΗΜΑ 2.6
PDF
ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 11
Η ΓΛΩΣΣΑ C++ - ΜΑΘΗΜΑ 4 - ΚΛΑΣΕΙΣ ΚΑΙ ΑΝΑΦΟΡΕΣ
C++ - ΜΑΘΗΜΑ 1 - ΕΙΣΑΓΩΓΗ ΚΑΙ ΣΧΕΣΗ ΜΕ ΤΗ C
ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 9
ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 6 (ΕΚΤΥΠΩΣΗ)
ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 5 - ΔΟΜΕΣ ΕΠΑΝΑΛΗΨΗΣ
Η ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 15 - ΣΥΝΑΡΤΗΣΕΙΣ ΕΙΣΟΔΟΥ
ΑΛΓΟΡΙΘΜΟΙ ΣΕ C - ΜΑΘΗΜΑ 1 - ΔΙΑΠΕΡΑΣΗ ΠΙΝΑΚΑ
ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 18
Η Γλώσσα C - Μάθημα 2
ΠΛΗ10 ΜΑΘΗΜΑ 2.8
Η ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 7 - ΠΙΝΑΚΕΣ
Η ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 16 - ΣΥΝΑΡΤΗΣΕΙΣ ΕΞΟΔΟΥ (ΕΚΤΥΠΩΣΗ)
ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 10
Η ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 8 - ΔΕΙΚΤΕΣ
Η ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 14 - ΕΜΒΕΛΕΙΑ ΜΕΤΑΒΛΗΤΩΝ
ΑΛΓΟΡΙΘΜΟΙ ΣΕ C - ΜΑΘΗΜΑ 2 - ΑΝΑΖΗΤΗΣΗ ΣΤΟΙΧΕΙΟΥ ΣΕ ΠΙΝΑΚΑ
Η ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 12
ΠΛΗ10 ΜΑΘΗΜΑ 2.4
ΠΛΗ10 ΜΑΘΗΜΑ 2.6
ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 11
Ad

Similar to ΓΛΩΣΣΑ C++ - ΜΑΘΗΜΑ 3 - ΚΛΑΣΕΙΣ ΚΑΙ ΔΕΙΚΤΕΣ (20)

PDF
OS_Processes_iteration12333333333333333333333333
PDF
Η ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 13 - ΔΟΜΕΣ
PDF
Advanced Notes on Pointers
PPT
Python Κεφ. 1.4 Δομή Επανάληψης
PDF
ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ ΣΕ C - ΜΑΘΗΜΑ 8
PDF
Stelios poulakakis daktylidis diploma thesis presentation
PPT
Python. 1 2 δομή ακολουθίας
PDF
ΠΛΗ31 ΜΑΘΗΜΑ 3.5
PDF
PROLOG - ΜΑΘΗΜΑ 4
PDF
ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 17 - ΕΠΙΚΟΙΝΩΝΙΑ ΜΕ ΤΟ ΛΕΙΤΟΥΡΓΙΚΟ ΣΥΣΤΗΜΑ
PPTX
Python - Bασικές Aρχές Προγραμματισμού - Κεφ. 3
PDF
ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 4 - ΤΕΛΕΣΤΕΣ και η ΔΟΜΗ ΕΛΕΓΧΟΥ
PPT
κεφαλαιο 3'
PDF
ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ ΣΕ C - ΜΑΘΗΜΑ 2
PDF
ΠΛΗ31 ΤΕΣΤ 15
PDF
Exercise3
PPT
ΑΕΠΠ ΚΕΦ 2
PPTX
Iterative Structure (Δομή Επανάληψης)
PDF
Evangelos papathomas diploma thesis presentation
PPTX
Evangelos Papathomas: Semantic Code Search in Software Repositories using Neu...
OS_Processes_iteration12333333333333333333333333
Η ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 13 - ΔΟΜΕΣ
Advanced Notes on Pointers
Python Κεφ. 1.4 Δομή Επανάληψης
ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ ΣΕ C - ΜΑΘΗΜΑ 8
Stelios poulakakis daktylidis diploma thesis presentation
Python. 1 2 δομή ακολουθίας
ΠΛΗ31 ΜΑΘΗΜΑ 3.5
PROLOG - ΜΑΘΗΜΑ 4
ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 17 - ΕΠΙΚΟΙΝΩΝΙΑ ΜΕ ΤΟ ΛΕΙΤΟΥΡΓΙΚΟ ΣΥΣΤΗΜΑ
Python - Bασικές Aρχές Προγραμματισμού - Κεφ. 3
ΓΛΩΣΣΑ C - ΜΑΘΗΜΑ 4 - ΤΕΛΕΣΤΕΣ και η ΔΟΜΗ ΕΛΕΓΧΟΥ
κεφαλαιο 3'
ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ ΣΕ C - ΜΑΘΗΜΑ 2
ΠΛΗ31 ΤΕΣΤ 15
Exercise3
ΑΕΠΠ ΚΕΦ 2
Iterative Structure (Δομή Επανάληψης)
Evangelos papathomas diploma thesis presentation
Evangelos Papathomas: Semantic Code Search in Software Repositories using Neu...
Ad

More from Dimitris Psounis (20)

PDF
Η ΓΛΩΣΣΑ C++ - ΜΑΘΗΜΑ 4 - ΚΛΑΣΕΙΣ ΚΑΙ ΑΝΑΦΟΡΕΣ (4διαφ)
PDF
ΓΛΩΣΣΑ C++ - ΜΑΘΗΜΑ 3 - ΚΛΑΣΕΙΣ ΚΑΙ ΔΕΙΚΤΕΣ (4δ)
PDF
Η ΓΛΩΣΣΑ C++ - ΜΑΘΗΜΑ 2 - ΕΙΣΑΓΩΓΗ ΣΤΙΣ ΚΛΑΣΕΙΣ (4 διαφ)
PDF
C++ - ΜΑΘΗΜΑ 1 - ΕΙΣΑΓΩΓΗ ΚΑΙ ΣΧΕΣΗ ΜΕ ΤΗ C (4sl/p)
PDF
ΠΛΗ20 ΕΠΑΝΑΛΗΠΤΙΚΟ ΔΙΑΓΩΝΙΣΜΑ 6
PDF
ΠΛΗ20 ΕΠΑΝΑΛΗΠΤΙΚΟ ΔΙΑΓΩΝΙΣΜΑ 5
PDF
ΠΛΗ10 ΚΑΡΤΕΣ ΜΑΘΗΜΑΤΟΣ 2.2 (ΕΚΤΥΠΩΣΗ)
PDF
ΠΛΗ10 ΚΑΡΤΕΣ ΜΑΘΗΜΑΤΟΣ 2.2
PDF
ΠΛΗ10 ΚΑΡΤΕΣ ΜΑΘΗΜΑΤΟΣ 2.1 (ΕΚΤΥΠΩΣΗ)
PDF
ΠΛΗ10 ΚΑΡΤΕΣ ΜΑΘΗΜΑΤΟΣ 2.1
PDF
ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ ΣΕ C - ΜΑΘΗΜΑ 7
PDF
ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ ΣΕ C - ΜΑΘΗΜΑ 8 (ΕΚΤΥΠΩΣΗ)
PDF
ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ ΣΕ C - ΜΑΘΗΜΑ 7 (ΕΚΤΥΠΩΣΗ)
PDF
ΠΛΗ31 - ΤΕΣΤ 33
PDF
ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ ΣΕ C - ΜΑΘΗΜΑ 6
PDF
ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ ΣΕ C - ΜΑΘΗΜΑ 6 (ΕΚΤΥΠΩΣΗ)
PDF
ΠΛΗ31 ΤΕΣΤ 32
PDF
ΠΛΗ31 ΤΕΣΤ 31
PDF
ΠΛΗ31 ΤΕΣΤ 30
PDF
ΠΛΗ10 ΤΕΣΤ 35
Η ΓΛΩΣΣΑ C++ - ΜΑΘΗΜΑ 4 - ΚΛΑΣΕΙΣ ΚΑΙ ΑΝΑΦΟΡΕΣ (4διαφ)
ΓΛΩΣΣΑ C++ - ΜΑΘΗΜΑ 3 - ΚΛΑΣΕΙΣ ΚΑΙ ΔΕΙΚΤΕΣ (4δ)
Η ΓΛΩΣΣΑ C++ - ΜΑΘΗΜΑ 2 - ΕΙΣΑΓΩΓΗ ΣΤΙΣ ΚΛΑΣΕΙΣ (4 διαφ)
C++ - ΜΑΘΗΜΑ 1 - ΕΙΣΑΓΩΓΗ ΚΑΙ ΣΧΕΣΗ ΜΕ ΤΗ C (4sl/p)
ΠΛΗ20 ΕΠΑΝΑΛΗΠΤΙΚΟ ΔΙΑΓΩΝΙΣΜΑ 6
ΠΛΗ20 ΕΠΑΝΑΛΗΠΤΙΚΟ ΔΙΑΓΩΝΙΣΜΑ 5
ΠΛΗ10 ΚΑΡΤΕΣ ΜΑΘΗΜΑΤΟΣ 2.2 (ΕΚΤΥΠΩΣΗ)
ΠΛΗ10 ΚΑΡΤΕΣ ΜΑΘΗΜΑΤΟΣ 2.2
ΠΛΗ10 ΚΑΡΤΕΣ ΜΑΘΗΜΑΤΟΣ 2.1 (ΕΚΤΥΠΩΣΗ)
ΠΛΗ10 ΚΑΡΤΕΣ ΜΑΘΗΜΑΤΟΣ 2.1
ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ ΣΕ C - ΜΑΘΗΜΑ 7
ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ ΣΕ C - ΜΑΘΗΜΑ 8 (ΕΚΤΥΠΩΣΗ)
ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ ΣΕ C - ΜΑΘΗΜΑ 7 (ΕΚΤΥΠΩΣΗ)
ΠΛΗ31 - ΤΕΣΤ 33
ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ ΣΕ C - ΜΑΘΗΜΑ 6
ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ ΣΕ C - ΜΑΘΗΜΑ 6 (ΕΚΤΥΠΩΣΗ)
ΠΛΗ31 ΤΕΣΤ 32
ΠΛΗ31 ΤΕΣΤ 31
ΠΛΗ31 ΤΕΣΤ 30
ΠΛΗ10 ΤΕΣΤ 35

Recently uploaded (8)

PPTX
Χειραφέτιση και Αναμόρφωση 4. Η Εθνοσυνέλευση του 1862-1864
PPTX
A digital marketing strategy presentation for Evangelos Venizelos
PPTX
Δριστά Κυριακή, Το καπλάνι της βιτρίνας της Άλκης Ζέη.pptx
PPTX
Γερμανίδου Δήμ., Αγκαθα Κρίστι.ΕΓΚΛΗΜΑ ΣΤΟΝ ΝΕΙΛΟ_pptx4.pptx
PPTX
Γερμανίδου Φωτεινή, Το πτώμα στη βιβλιοθήκη.pptx
PPTX
Δούλια Θάλεια, Καρδιά Πάνω σε Ρόδες -Άντρη Αντωνίου- τελική Βιβλιοπαρουσίαση....
PPTX
Γρηγοριάδου Ανθή Μαρία, Τα Ψηλά Βουνά του Ζαχαρία Παπαντωνίου.pptx
PPTX
A digital marketing strategy presentation for Evangelos Venizelos
Χειραφέτιση και Αναμόρφωση 4. Η Εθνοσυνέλευση του 1862-1864
A digital marketing strategy presentation for Evangelos Venizelos
Δριστά Κυριακή, Το καπλάνι της βιτρίνας της Άλκης Ζέη.pptx
Γερμανίδου Δήμ., Αγκαθα Κρίστι.ΕΓΚΛΗΜΑ ΣΤΟΝ ΝΕΙΛΟ_pptx4.pptx
Γερμανίδου Φωτεινή, Το πτώμα στη βιβλιοθήκη.pptx
Δούλια Θάλεια, Καρδιά Πάνω σε Ρόδες -Άντρη Αντωνίου- τελική Βιβλιοπαρουσίαση....
Γρηγοριάδου Ανθή Μαρία, Τα Ψηλά Βουνά του Ζαχαρία Παπαντωνίου.pptx
A digital marketing strategy presentation for Evangelos Venizelos

ΓΛΩΣΣΑ C++ - ΜΑΘΗΜΑ 3 - ΚΛΑΣΕΙΣ ΚΑΙ ΔΕΙΚΤΕΣ

  • 1. H ΓΛΩΣΣΑ C++ Μάθημα 3: Κλάσεις και Δείκτες Δημήτρης Ψούνης
  • 2. Περιεχόμενα Μαθήματος Α. Θεωρία 1. Διαχείριση Μνήμης 1. Στατική Δέσμευση Μνήμης 2. Στατική Δέσμευση Μνήμης για Συνήθεις Μεταβλητές 3. Στατική Δέσμευση Μνήμης για Αντικείμενα 2. Δυναμική Δέσμευση Μνήμης 1. Δείκτες (Υπενθύμιση από C) 2. Οι τελεστές new και delete 3. Δυναμική Δέσμευση για Συνήθεις Μεταβλητές 4. Δυναμική Δέσμευση για Αντικείμενα 5. Δυναμική Δέσμευση και Κατασκευαστές 2Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες 3. Κλάσεις που περιέχουν δείκτες 1. Παράδειγμα κλάσης που περιέχει δείκτες 2. …και ένα πρόβλημα (χωρίς λύση για την ώρα) 4. Δυναμική Δέσμευση Μνήμης για Πίνακες 1. Μονοδιάστατοι πίνακες 2. Παράδειγμα δέσμευσης μνήμης για μονοδιάστατους πίνακες 3. Διδιάστατοι πίνακες 4. Παράδειγμα δέσμευσης μνήμης για διδιάστατους πίνακες B. Ασκήσεις
  • 3. A. Θεωρία 1. Διαχείριση Μνήμης 1. Στατική και Δυναμική Δέσμευση Μνήμης 3Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες • Η διαχείριση μνήμης στη C++ γίνεται με παρόμοιο τρόπο με τη C. • Τα παρακάτω είναι εντελώς αντίστοιχα: • Στατική Δέσμευση Μνήμης: • Είναι γνωστός εκ των προτέρων ο χώρος μνήμης που απαιτείται για τα στιγμιότυπα. • Και έχει ήδη αποφασιστεί κατά το χρόνο μεταγλώττισης (π.χ. δηλώνουμε έναν πίνακα 10 θέσεων) • Οι τοπικές μεταβλητές αποθηκεύονται στον χώρο της συνάρτησης (στοίβα – stack) • Δυναμική Δέσμευση Μνήμης: • Δεν είναι γνωστός εκ των προτέρων ο χώρος μνήμης που πρέπει να δεσμεύσει το πρόγραμμά μας. • Αλλά αποφασίζεται κατά το χρόνο εκτέλεσης (π.χ. ο χρήστης αποφασίζει πόσες θέσεις θα έχει ένας πίνακας που χρησιμοποιεί το πρόγραμμα) • Ο χώρος μνήμης που δεσμεύεται δυναμικά είναι κοινός για όλες τις συναρτήσεις (σωρός – heap)
  • 4. A. Θεωρία 1. Διαχείριση Μνήμης 2. Στατική Δέσμευση μνήμης για συνήθεις μεταβλητές 4Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες /* CPP3.local_variables.cpp */ #include <iostream> using namespace std; void f() { int y=3; cout<<"inside f"; } int main() { int x=5; cout<<"inside main"; f(); return 0; } • Κάθε συνάρτηση έχει το δικό της χώρο μνήμης. • Κάθε τοπική μεταβλητή αποθηκεύεται στο χώρο μνήμης της συνάρτησης στην οποία ανήκει. • Σχηματικά, για το παράδειγμα: • Αυτός ο χώρος μνήμης καλείται και στοίβα (stack), λόγω του τρόπου με τον οποίο εχει υλοποιηθεί η κλήση των συναρτήσεων σε μία στοίβα: main f
  • 5. A. Θεωρία 1. Διαχείριση Μνήμης 3. Στατική Δέσμευση μνήμης για Αντικείμενα 5Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες • Ένα αντικείμενο αποθηκεύεται στη μνήμη ως εξής: • Τα μέλη του βρίσκονται σε διαδοχικές θέσεις μνήμης • Προσοχή, οι μέθοδοι βρίσκονται σε άλλο χώρο (είναι κοινές για όλα τα αντικείμενα της κλάσης) • Ο τελεστής sizeof μπορεί να χρησιμοποιήθεί για να μετρήσουμε το πλήθος των bytes που χρησιμοποιεί ένα αντικείμενο. • Παράδειγμα: /* CPP3.sizeof.cpp Μέγεθος αντικειμένου */ #include <iostream> using namespace std; class dummy { public: int x; int y; }; int main() { dummy ob; ob.x = 3; ob.y = 5; cout<<sizeof ob<<endl; return 0; } • Θα τυπώσει 8 (δύο ακέραιοι 4bytes ο καθένας) • Και η εικόνα της μνήμης:
  • 6. A. Θεωρία 2. Δυναμική Δέσμευση Μνήμης 1. Δείκτες (Υπενθύμιση από C) 6Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες • Ένας δείκτης είναι μια μεταβλητή που αποθηκεύει διευθύνσεις μεταβλητών • Ένας δείκτης δηλώνεται ως εξής: • Όπου ΤΔ είναι ένας οποιοσδήποτε τύπος δεδομένων (int, float, double κ.λπ.) • Π.χ. ένας δείκτης σε ακέραιο δηλώνεται με τη δήλωση: • Αποθηκεύουμε σε έναν δείκτη την διεύθυνση μιας μεταβλητής με τη δήλωση: • O τελεστής & επιστρέφει τη διεύθυνση της μεταβλητής στην οποία εφαρμόζεται. • Π.χ. αποθηκεύουμε στον δείκτη ptr τη διεύθυνση μιας μεταβλητής x με την εντολή: • και λέμε «ο δείκτης ptr δείχνει στην μεταβλητή x» ΤΔ *pointer_name; int *ptr; pointer_name = &variable; ptr = &x; • Αναλυτικά βλ. και «Γλώσσα C – Μάθημα 8: Δείκτες»
  • 7. A. Θεωρία 2. Δυναμική Δέσμευση Μνήμης 1. Δείκτες (Υπενθύμιση από C) 7Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες /* CPP3.pointers.cpp */ #include <iostream> using namespace std; int main() { int x=5; int *p = NULL; p = &x; cout<<"x = "<<x<<" (address: "<<&x<<")"<<endl; cout<<"*p = "<<*p<<" (address: "<<p<<")"<<endl; return 0; } • Το πρόγραμμα δείχνει την βασική ιδιότητα: • Για ένα δείκτη (p) που «δείχνει» σε μία μεταβλητη ισχύουν: • To NULL είναι μία ειδική τιμή • που συμβολίζει ότι ο δείκτης δεν δείχνει κάπου. • Είναι καλό ένας δείκτης που δεν δείχνει κάπου να έχει την τιμή NULL • H τιμη του NULL είναι 0. • Σχηματικά: p == &x //Διεύθυνση της x *p == x // Τιμή της x
  • 8. A. Θεωρία 2. Δυναμική Δέσμευση Μνήμης 2. Οι τελεστές new και delete 8Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες • Ο τελεστής new χρησιμοποιείται για να δεσμεύσει δυναμικά χώρο μνήμης • Αντικαθιστά τη malloc της C. • Η σύνταξη του είναι: • Δεσμεύει χώρο μνήμης για ένα αντικείμενου τύπου type και επιστρέφει έναν δείκτη σε αυτόν το χώρο • Ο χώρος μνήμης που δεσμεύεται δυναμικά, είναι κοινός για όλες τις συναρτήσεις και ονομάζεται σωρός (heap) • Προσοχή, αν αποτύχει η δέσμευση (δεν υπάρχει χώρος) επιστρέφει NULL • και θα πρέπει πάντα να ελέγχουμε ότι η δέσμευση έγινε επιτυχημένα ptr = new type; • Ο τελεστής delete χρησιμοποιείται για να απόδεσμευσει χώρο μνήμης που έχει δεσμευτεί δυναμικά • Αντικαθιστά τη free της C. • Η σύνταξη του είναι: delete ptr;
  • 9. A. Θεωρία 2. Δυναμική Δέσμευση Μνήμης 2. Οι τελεστές new και delete (Έλεγχος Δέσμευσης Μνήμης) 9Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες • Πάντα πρέπει να κάνουμε έλεγχο αν η μνήμη που αιτηθήκαμε με τη new, έχει όντως δεσμευτεί. • Βλέπουμε τρεις τρόπους για να «πιάσουμε» το πρόβλημα: • A’ τρόπος: Ο πιο απλός, μιας και απλά ελέγχουμε την επιστρεφόμενη τιμή: • Β’ τρόπος: Πιο ψαγμένος, ξέρουμε ότι το NULL είναι 0 (και για να είμαστε ακριβής (void *) 0) • Και ξέρουμε ότι το 0, είναι το λογικό ψευδές • και το !0 είναι το λογικό αληθές: • Γ’τρόπος: Ο πιο σύνθετος και φαντεζί, αλλά ενσωματώνει τις δύο εντολές σε μία γραμμή: • Στις σημειώσεις θα χρησιμοποιήσουμε κυρίως το Β’ τρόπο • Και θα βγάζουμε απλά ένα ενημερωτικό μήνυμα (αργότερα θα μπορούμε να κάνουμε και περισσότερα πράγματα, με τις εξαιρέσεις της C++) ptr = new type; if (ptr==NULL) { …. do some action… } ptr = new type; if (!ptr) { …. do some action… } if (!(ptr = new type)) { …. do some action… }
  • 10. A. Θεωρία 2. Δυναμική Δέσμευση Μνήμης 3. Δυναμική Δέσμευση για Συνήθεις Μεταβλητές 10Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες • Το παράδειγμα δείχνει τη δέσμευση μνήμης για έναν ακέραιο αριθμό, τόσο στατικά όσο και δυναμικά: #include <iostream> // CPP3.dynamic_variable.cpp using namespace std; int main() { int x; // Μεταβλητή που δεσμέυει στατικό χώρο int *p; // Δείκτης σε ακέραιο p = new int; // Δυναμική δέσμευση μνήμης if (!p) cout<<“Error allocating memory”; /* Αναθέσεις τιμών */ x = 1; *p = 5; /* Εκτυπώσεις */ cout<<"x = "<<x<<" (address: "<<&x<<")"<<endl; cout<<"*p = "<<*p<<" (address: "<<p<<")"<<endl; delete p; // Αποδέσμευση μνήμης return 0; } Υπενθυμίσεις από τη C: • Η x δεσμεύει χώρο μνήμης μέσα στο χώρο μνήμης της συνάρτησης • Ο χώρος που δεσμεύεται δυναμικά μέσω της p, είναι ένας ξεχωριστός χώρος, κοινός για όλο το πρόγραμμα • (λέγεται και σωρός – heap) • Σχηματικά:
  • 11. A. Θεωρία 2. Δυναμική Δέσμευση Μνήμης 4. Δυναμική Δέσμευση για Αντικείμενα 11Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες /* CPP3.dynamic_object.cpp Δυναμική Δέσμευση μνήμης για αντικείμενο */ #include <iostream> using namespace std; class dummy { public: int x; }; int main() { dummy *p = NULL; //Θα δείξει σε αντικείμενο p = new dummy; // Δέσμευση χώρου if (!p) cout<<“Error allocating memory”; /* Αναθέσεις τιμών */ p->x = 5; /* Εκτυπώσεις */ cout<<"p->x = "<<p->x<<endl; delete p; // Αποδέσμευση μνήμης return 0; } • Αντίστοιχα (αφού μία κλάση είναι τύπος δεδομένων), μπορεί να δεσμευτεί δυναμικά χώρος μνήμης για ένα αντικείμενο. • Όταν χρησιμοποιούμε ένα αντικείμενο μέσω δείκτη, • Έχουμε πρόσβαση στα δημόσια μέλη-μεθόδους μέσω του τελεστή -> (βελάκι) • Βλέπουμε και ένα παράδειγμα:
  • 12. A. Θεωρία 2. Δυναμική Δέσμευση Μνήμης 4. Δυναμική Δέσμευση για Αντικείμενα 12Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες /* CPP3.dereferencing.cpp */ #include <iostream> using namespace std; class dummy { public: int x; }; int main() { dummy *p = NULL; //Θα δείξει σε αντικείμενο p = new dummy; // Δέσμευση χώρου if (!p) cout<<“Error allocating memory”; /* Αναθέσεις τιμών */ (*p).x = 5; /* Εκτυπώσεις */ cout<<"(*p).x = "<<(*p).x<<endl; delete p; // Αποδέσμευση μνήμης return 0; } • Δεδομένου ενός δείκτη που δείχνει σε ένα αντικείμενο. • Με τον τελεστή *, έχουμε πρόσβαση στο ίδιο το αντικείμενο (dereferencing) • Και ισχύει ότι το (*p) είναι το αντικείμενο στο οποίο δείχνει ο δείκτης. • Συνεπώς έχουμε πρόσβαση στα δημόσια μέλη του (*p) με τον τελεστή . (τελεία) • Βλέπουμε και ένα παράδειγμα:
  • 13. A. Θεωρία 2. Δυναμική Δέσμευση Μνήμης 4. Δυναμική Δέσμευση για Αντικείμενα 13Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες /* CPP3.pointers_and_objects.cpp Δείκτης σε αντικείμενο */ #include <iostream> using namespace std; class dummy { public: int x; }; int main() { dummy ob; dummy *p = &ob; if (!p) cout<<“Error allocating memory”; /* Αναθέσεις τιμών */ ob.x = 6; /* Εκτυπώσεις */ cout<<ob.x<<" "<<p->x<<" "<<(*p).x<<endl; return 0; } • Και ένα ακόμη παράδειγμα, όπου βάζουμε ένα δείκτη να δείχνει σε ένα ήδη υφιστάμενο αντικείμενο: • Για να τονιστεί η διαφορά στην πρόσβαση, • απευθείας από το αντικείμενο (τελεστής .) • μέσω δείκτη (τελεστής ->) • μέσω dereferencing ( * και . )
  • 14. A. Θεωρία 2. Δυναμική Δέσμευση Μνήμης 5. Δυναμική Δέσμευση και κατασκευαστές 14Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες • Όταν δημιουργούμε ένα αντικείμενο με τον τελεστή new, • και εφόσον το αντικείμενο αυτό έχει κατασκευαστή • πρέπει να περάσουμε και τα ορίσματα στον κατασκευαστή • Ο κατασκευαστής καλείται όταν κάνουμε new • Ο καταστροφέας καλείται όταν κάνουμε delete /* CPP3.constructor_destru ctor.cpp */ #include <iostream> using namespace std; class dummy { public: dummy(int in_x); ~dummy(); private: int x; }; int main() { dummy *p = NULL; p = new dummy(5); //constructing if (!p) cout<<“Error allocating memory”; delete p; //destructing return 0; } dummy::dummy(int in_x) { x = in_x; cout<<"Constructing..."; } dummy::~dummy() { cout<<"Destructing..."; }
  • 15. A. Θεωρία 3. Κλάσεις που περιέχουν δείκτες 1. Παράδειγμα κλάσης που περιέχει δείκτη 15Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες • Ένας δείκτης είναι απλά μία μεταβλητή • Συνεπώς μπορεί να είναι μέλος σε κλάση • Βλέπουμε ένα απλό παράδειγμα: • Στο οποίο δεσμεύουμε δυναμικά στον κατασκευαστή το χώρο για έναν ακέραιο • και τον αποδεσμεύουμε στον καταστροφέα. /* CPP3.class_with_pointer */ #include <iostream> using namespace std; class dummy { public: dummy(); ~dummy(); void set_val(int in_val); int get_val(); private: int *p_val; };
  • 16. A. Θεωρία 3. Κλάσεις που περιέχουν δείκτες 1. Παράδειγμα κλάσης που περιέχει δείκτη 16Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες int main() { dummy ob; ob.set_val(3); cout<<endl<<ob.get_val()<<endl; return 0; } dummy::dummy() { p_val = new int; if (!p_val) cout<<"Error allocating memory"; cout<<"Constructing..."; } dummy::~dummy() { delete p_val; cout<<"Destructing..."; } void dummy::set_val(int in_val) { *p_val = in_val; } int dummy::get_val() { return *p_val; }
  • 17. A. Θεωρία 3. Κλάσεις που περιέχουν δείκτες 2. …και ένα πρόβλημα (χωρίς λύση για την ώρα) 17Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες • Ας δούμε και ένα πρόβλημα που μπορεί να προκύψει όταν μία κλάση περιέχει δείκτες που κάνουν δυναμική διαχείριση μνήμης • Το πρόβλημα αυτό προκύπτει όταν: • Έχουμε μία κλάση που κάνει δυναμική δέσμευση μνήμης • Κάνουμε αντιγραφή του αντικειμένου (π.χ. ob1 = ob2) • Μεταγλωττίστε και εκτελέστε το ακόλουθο πρόγραμμα: /* CPP3.assignment_problem Δυναμική Δέσμευση και Τελεστής Ανάθεσης */ #include <iostream> using namespace std; class dummy { public: dummy(); ~dummy(); void set_val(int in_val); int get_val(); private: int *p_val; };
  • 18. A. Θεωρία 3. Κλάσεις που περιέχουν δείκτες 2. …και ένα πρόβλημα (χωρίς λύση για την ώρα) 18Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες int main() { dummy ob1; ob1.set_val(3); dummy ob2; ob2 = ob1; cout<<ob1.get_val()<<endl; cout<<ob2.get_val()<<endl; return 0; } dummy::dummy() { p_val = new int; if (!p_val) cout<<"Error allocating memory"; cout<<"Constructing..."; } dummy::~dummy() { delete p_val; cout<<"Destructing..."; } void dummy::set_val(int in_val) { *p_val = in_val; } int dummy::get_val() { return *p_val; } • Σημαντικό! Στη C++ οι μεταβλητές μπορούν να δηλωθούν σε οποιοδήποτε μέρος του προγράμματος (αλλά θα το αποφεύγουμε…)
  • 19. A. Θεωρία 3. Κλάσεις που περιέχουν δείκτες 2. …και ένα πρόβλημα (χωρίς λύση για την ώρα) 19Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες • H εκτέλεση του προγράμματος οδηγεί σε σφάλμα κατά το χρόνο εκτέλεσης: • Για να καταλάβουμε γιατί συμβαίνει αυτό, θα δούμε την κατάσταση της μνήμης βήμα – βήμα κατά την εκτέλεση της main
  • 20. A. Θεωρία 3. Κλάσεις που περιέχουν δείκτες 2. …και ένα πρόβλημα (χωρίς λύση για την ώρα) 20Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες • dummy ob1; // Δεσμεύει το χώρο για το ob1. • ob1.set_val(3); // αποθηκεύει την τιμή 3 στο χώρο μνήμης
  • 21. A. Θεωρία 3. Κλάσεις που περιέχουν δείκτες 2. …και ένα πρόβλημα (χωρίς λύση για την ώρα) 21Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες • dummy ob2; // Δεσμεύει το χώρο για το ob2. • ob2=ob1 // Δεν κάνει ακριβώς αυτό που θέλουμε…
  • 22. A. Θεωρία 3. Κλάσεις που περιέχουν δείκτες 2. …και ένα πρόβλημα (χωρίς λύση για την ώρα) 22Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες • Τώρα με την ολοκλήρωση του προγράμματος, θα τρέξουν οι δύο destructors. • Συνεπώς ο ίδιος χώρος μνήμης θα αποδεσμευτεί δύο φορές. • Και αυτό οδηγεί σε σφάλμα στο χρόνο εκτέλεσης. • Ενώ ισχύει ότι έχουμε κάνει και το βασικό λάθος • Με την ολοκλήρωση του προγράμματος, έχει ξεμείνει χώρος μνήμης, τον οποίο δεσμεύσαμε δυναμικά και δεν τον αποδεσμεύσαμε ποτέ (memory leak) • Το πρόβλημα αυτό προκύπτει όταν γίνεται bit by bit αντιγραφή αντικειμένων (shallow copy) • όπως στην περίπτωση που είδαμε, • αλλά και σε άλλες περιπτώσεις (π.χ. όταν περνάμε ένα αντικείμενο μέσω τιμής σε μία συνάρτηση) • Θα αντιμετωπίσουμε το πρόβλημα αυτό, στα επόμενα μαθήματα: • Θα μάθουμε τις αναφορές (references) • και μέσω αυτών θα ορίσουμε τον κατασκευαστή αντιγράφου (copy constructor) • επίσης θα μάθουμε την υπερφόρτωση του = • και θα ορίσουμε τι πρέπει να γίνεται όταν έχουμε ανάθεση αντικειμένου
  • 23. A. Θεωρία 4. Δυναμική Δέσμευση Μνήμης για Πίνακες 1. Μονοδιάστατοι Πίνακες 23Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες • Οι τελεστές new και delete χρησιμοποιούνται και για την δέσμευση μνήμης για πίνακες • Δέσμευση Μνήμης: • Η σύνταξη του τελεστή new είναι: • Δεσμεύει χώρο μνήμης για n αντικείμενα τύπου type και επιστρέφει έναν δείκτη σε αυτόν το χώρο • Το n δεν χρειάζεται να είναι σταθερά. • Αποδέσμευση Μνήμης: • Η σύνταξη του τελεστή delete είναι: ptr = new type [n]; delete [] ptr;
  • 24. • Βλέπουμε και ένα παράδειγμα δέσμευσης μνήμης για έναν πίνακα n ακεραίων. A. Θεωρία 4. Δυναμική Δέσμευση Μνήμης για Πίνακες 2. Παράδειγμα δέσμευσης μνήμης για μονοδιάστατο πίνακα 24Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες /* CPP3.1d_dynamic_array Μονοδιάστατος πίνακας με δυναμική δέσμευση μνήμης */ #include <iostream> using namespace std; int main() { int *arr; int n=4; /* Δέσμευση Μνήμης */ arr = new int [n]; if (!arr) cout<<"Error allocating memory!"; /* Κάποια δουλειά στον πίνακα */ for (int i=0; i<n; i++) arr[i]=i*i; for (int i=0; i<n; i++) cout<<arr[i]<<" "; /* Αποδέσμευση Μνήμης */ delete [] arr; return 0; }
  • 25. A. Θεωρία 4. Δυναμική Δέσμευση Μνήμης για Πίνακες 3. Διδιάστατοι Πίνακες 25Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες • Ένας διδιάστατος ΜxN πίνακας π.χ. ακεραίων είναι: • ένας πίνακας M δεικτών σε ακέραιο • όπου κάθε δείκτης είναι ένας πίνακας από N ακεραίους • Σχηματικά (π.χ. για M=7, N=6): 1 5 2 4 3 2 6 4 6 9 3 4 2 5 9 4 6 2 1 8 9 6 2 3 9 1 5 1 6 7 9 8 4 1 3 5 1 9 7 6 4 2pin[6] pin[1] pin[2] pin[3] pin[4] pin[5] pin[0] pin pin[0][4] pin[3][3] pin[6][0] M=7 γραμμές Ν=6 στήλες
  • 26. A. Θεωρία 4. Δυναμική Δέσμευση Μνήμης για Πίνακες 3. Διδιάστατοι Πίνακες 26Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες • Από τα παραπάνω: • Η δέσμευση μνήμης θα γίνει με τις εντολές: • Προσοχή, ότι το ptr είναι διπλός δείκτης • αφου θέλουμε να δείχνει στην διεύθυνση μιας μεταβλητής που είναι διεύθυνση ενός τύπου. • Συνεπώς θα δηλωθεί ως: • H αποδέσμευση θα γίνει εντολές: ptr = new type * [Μ]; for (i=0; i<M; i++) ptr[i] = new type [N]; type **ptr; for (i=0; i<M; i++) delete [] ptr[i]; delete [] ptr;
  • 27. • Βλέπουμε και ένα παράδειγμα δέσμευσης μνήμης για έναν πίνακα n ακεραίων. A. Θεωρία 4. Δυναμική Δέσμευση Μνήμης για Πίνακες 4. Παράδειγμα δέσμευσης μνήμης για διδιάστατο πίνακα 27Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες /* CPP3.2d_dynamic_array Διδιάστατος πίνακας με δυναμική δέσμευση μνήμης */ #include <iostream> using namespace std; int main() { int **arr; int i,j, n=3, m=5; /* Δέσμευση Μνήμης */ arr = new int * [n]; if (!arr) cout<<"Error allocating memory!"; for (i=0; i<n; i++) { arr[i] = new int [m]; if (!arr[i]) cout<<"Error allocating memory!"; } /* Κάποια δουλειά στον πίνακα */ for (i=0; i<n; i++) for (j=0; j<m; j++) arr[i][j]=i*j; for (i=0; i<n; i++) { for (j=0; j<m; j++) cout<<arr[i][j]; cout<<endl; } /* Αποδέσμευση Μνήμης */ for (i=0; i<n; i++) delete [] arr[i]; delete [] arr; return 0; }
  • 28. Β. Ασκήσεις Άσκηση 1: Διπλοί Δείκτες 28Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες Για να πειραματιστούμε με τους δείκτες • Δηλώστε μία ακέραια μεταβλητή x • Τυπώστε την τιμή και τη διεύθυνσή της • Δηλώστε έναν δείκτη σε ακέραιο p • Θέστε τον να δείχνει στην x • Τυπώστε την τιμή και τη διεύθυνση του • Τυπώστε την τιμή του x, μέσω του p. • Δηλώστε έναν δείκτη σε δείκτη σε ακέραιο, με όνομα pp • Θέστε τον να δείχνει στον p • Τυπώστε την τιμή και τη διεύθυνσή του • Τυπώστε την τιμή του x, μέσω του pp. • Τυπώστε την τιμή του p, μέσω του pp.
  • 29. Β. Ασκήσεις Άσκηση 2: Κλάση Δυναμικός Πίνακας 29Δημήτρης Ψούνης, Η Γλώσσα C++, Μάθημα 3: Κλάσεις και Δείκτες Κατασκευάστε μία κλάση (ARRAY) που να περιτυλίσσει την έννοια του μονοδιάστατου πίνακα ως εξής: • Να έχει ως μέλη έναν δυναμικό πίνακα (δείκτης) ακεραίων, καθώς και τη διάσταση του πίνακα • Ο κατασκευαστής να παίρνει ως όρισμα τη διάσταση του πίνακα και να δεσμεύει δυναμικά το χώρο μνήμης που απαιτείται. • Ο καταστροφέας να διαγράφει τη μνήμη που έχει δεσμευτεί δυναμικά. • Να έχει accessors για ένα στοιχείο του πίνακα • Να τυπώνουν μήνυμα λάθους, σε περίπτωση πρόσβασης εκτός των ορίων του πίνακα. • Μία μέθοδο print που να τυπώνει τα στοιχείτα του πίνακα Η συνάρτηση main • Να κατασκευάζει έναν πίνακα της κλάσης με 10 θέσεις • Να αρχικοποιεί τα στοιχεία του πίνακα, ώστε κάθε στοιχείο να έχει το τετράγωνο της αντίστοιχης θέσης. • Να τυπώνει τον πίνακα. Ποιο πρόβλημα υπάρχει με την υλοποίηση; Πότε περιμένουμε ότι το πρόγραμμα αυτό θα έχει πρόβλημα και θα «σκάσει» κατά το χρόνο εκτέλεσης;