====== Δυναμική διαχείριση μνήμης ======
Όπως και στη C έτσι και στη C++ η μνήμη μπορεί να δεσμευθεί δυναμικά στο χώρο δεδομένων που ονομάζεται //heap//. Εκτός των συναρτήσεων [[http://www.cplusplus.com/reference/cstdlib/malloc/|malloc]] και [[http://www.cplusplus.com/reference/cstdlib/free/|free]] που εξακολουθούν να υφίστανται και στη C++, ορίζονται οι τελεστές **new** και **delete** για δέσμευση και αποδέσμευση μνήμης.
Δεν θα πρέπει να συγχέεται ποτέ η χρήση **malloc/free** με **new/delete** για τη δέσμευση και αποδέσμευση μνήμης. Οποιοσδήποτε χώρος δεν δεσμεύτηκε με //malloc// θα πρέπει να ελευθερωθεί με //free//. Αντίστοιχα ότι δεσμεύθηκε με //new// θα πρέπει να ελευθερωθεί με //delete//.
Οι τελεστής **new** εκτός από τη δέσμευση μνήμης επιτρέπει και τη αρχικοποίηση μεταβλητών βασικού ή αναφορικού τύπου με χρήση του αντίστοιχου κατασκευαστή.
Ο τελεστής **new** έχει δύο μορφές (**new** και **new[]**). Η πρώτη χρησιμοποιείται για την δέσμευση μνήμης ενός αντικειμένου ή μιας μεταβλητής βασικού τόπου, ενώ η δεύτερη για τη δέσμευση μνήμης και την αρχικοποίηση ενός πίνακα.
Σε αναλογία με τον τελεστή **new** ο τελεστής **delete** για την αποδέσμευση μνήμης έχει και αυτός δύο μορφές (**delete** και **delete[]**). Η πρώτη χρησιμοποιείται για την αποδέσμευση μνήμης ενός αντικειμένου ή μιας μεταβλητής βασικού τϋπου, ενώ η δεύτερη για την αποδέσμευση μνήμης ενός πίνακα. Δείτε το παρακάτω παράδειγμα χρήσης των τελεστών **new** και **delete**.
#include
using namespace std;
int main () {
int *num, *p;
num = new int;
cout << "Enter number of elements: ";
cin >> *num;
p = new int[*num];
for(int i=0; i<*num; i++) {
cout << "Next integer: ";
cin >> p[i];
}
for(int i=0; i<*num; i++) {
cout << p[i] << "\t";
}
cout << endl;
delete []p;
delete num;
}
Για βασικούς τύπους δεδομένων μπορείτε να αρχικοποιήσετε τη μεταβλητή ως εξής, με χρήση του τελεστή **new**:
#include
using namespace std;
int main () {
int *num_ptr;
num_ptr = new int(5); // δέσμευση μνήμης και ανάθεση της τιμής 5
// στο περιεχόμενο της διεύθυνσης αυτής.
cout << "num: " << num_ptr;
}
===== Έλεγχος δέσμευσης μνήμης =====
Κατά τη δέσμευση μνήμης δεν είναι απαραίτητο να γίνονται οι έλεγχοι για το κατά πόσο η δέσμευση απέτυχε. Στην περίπτωση που η δέσμευση μνήμης αποτύχει τότε παράγεται ένα //exception// τύπου ''bad_alloc'' το οποίο καλούμαστε να διαχειριστούμε, διαφορετικά το πρόγραμμα θα τερματίσει. Εάν δεν επιθυμούμε ο τελεστής **new** να παράξει //exception//, θα πρέπει να αλλάξουμε τον τρόπο κλήσης προσθέτοντας τη δεσμευμένη έκφραση ''(nothrow)'' αμέσως μετά τον τελεστή **new** και να ελέγξουμε την επιστρεφόμενη τιμή ως εξής:
#include
using namespace std;
int main () {
int *num, *p;
num = new int;
cout << "Enter number of elements: ";
cin >> *num;
p = new (nothrow) int[*num];
if(p==NULL) {
cout << "Allocation failure!\n";
return 0;
}
for(int i=0; i<*num; i++) {
cout << "Next integer: ";
cin >> p[i];
}
for(int i=0; i<*num; i++) {
cout << p[i] << "\t";
}
cout << endl;
delete []p;
delete num;
}
===== Παράδειγμα δέσμευσης μνήμης για την αρχικοποίηση ενός διδιάστατου πίνακα =====
#include
#include
using namespace std;
int main(int argc, char *argv[]) {
int **array2d, rows, columns;
cout << "Enter number of rows: ";
cin >> rows;
cout << "Enter number of columns: ";
cin >> columns;
array2d = new (nothrow) int*[rows];
if(array2d == NULL) {
cerr < "Memory allocation error!\n";
return -1;
}
for(int i=0; i