User Tools

Site Tools


cpp:dynamic_memory

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Previous revision
cpp:dynamic_memory [2021/04/27 05:01]
cpp:dynamic_memory [2021/04/27 06:01]
gthanos [Έλεγχος δέσμευσης μνήμης]
Line 1: Line 1:
 +====== Δυναμική διαχείριση μνήμης ======
 +
 +Όπως και στη C έτσι και στη C++ η μνήμη μπορεί να δεσμευθεί δυναμικά στο χώρο δεδομένων που ονομάζεται //heap//. Εκτός των συναρτήσεων [[http://www.cplusplus.com/reference/cstdlib/malloc/|malloc]] και [[http://www.cplusplus.com/reference/cstdlib/free/|free]] που εξακολουθούν να υφίστανται και στη C++, ορίζονται οι τελεστές **new** και **delete** για δέσμευση και αποδέσμευση μνήμης. 
 +
 +<WRAP center round tip 80%>
 +Δεν θα πρέπει να συγχέεται ποτέ η χρήση **malloc/free** με **new/delete** για τη δέσμευση και αποδέσμευση μνήμης. Οποιοσδήποτε χώρος δεν δεσμεύτηκε με //malloc// θα πρέπει να ελευθερωθεί με //free//. Αντίστοιχα ότι δεσμεύθηκε με //new// θα πρέπει να ελευθερωθεί με //delete//.
 +
 +Οι τελεστής **new** εκτός από τη δέσμευση μνήμης επιτρέπει και τη αρχικοποίηση μεταβλητών βασικού ή αναφορικού τύπου με χρήση του αντίστοιχου κατασκευαστή.
 +</WRAP>
 +
 +Ο τελεστής **new** έχει δύο μορφές (**new** και **new[]**). Η πρώτη χρησιμοποιείται για την δέσμευση μνήμης ενός αντικειμένου ή μιας μεταβλητής βασικού τόπου, ενώ η δεύτερη για τη δέσμευση μνήμης και την αρχικοποίηση ενός πίνακα. 
 +
 +Σε αναλογία με τον τελεστή **new** ο τελεστής **delete** για την αποδέσμευση μνήμης έχει και αυτός δύο μορφές (**delete** και **delete[]**). Η πρώτη χρησιμοποιείται για την αποδέσμευση μνήμης ενός αντικειμένου ή μιας μεταβλητής βασικού τϋπου, ενώ η δεύτερη για την αποδέσμευση μνήμης ενός πίνακα. Δείτε το παρακάτω παράδειγμα χρήσης των τελεστών **new** και **delete**.
 +
 +<code c++ dynamic_memory.cpp>
 +#include <iostream>
 +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;
 +}
 +</code>
 +
 +Για βασικούς τύπους δεδομένων μπορείτε να αρχικοποιήσετε τη μεταβλητή ως εξής, με χρήση του τελεστή **new**:
 +
 +<code c++ dynamic_memory2.cpp>
 +#include <iostream>
 +using namespace std;
 +
 +int main () {
 +  int *num_ptr;
 +  num_ptr = new int(5);     // δέσμευση μνήμης και ανάθεση της τιμής 5
 +                            // στο περιεχόμενο της διεύθυνσης αυτής.
 +  cout << "num: " << num_ptr;
 +}
 +</code>
 +
 +===== Έλεγχος δέσμευσης μνήμης =====
 +
 +Κατά τη δέσμευση μνήμης δεν είναι απαραίτητο να γίνονται οι έλεγχοι για το κατά πόσο η δέσμευση απέτυχε. Στην περίπτωση που η δέσμευση μνήμης αποτύχει τότε παράγεται ένα //exception// τύπου ''bad_alloc'' το οποίο καλούμαστε να διαχειριστούμε, διαφορετικά το πρόγραμμα θα τερματίσει. Εάν δεν επιθυμούμε ο τελεστής **new** να παράξει //exception//, θα πρέπει να αλλάξουμε τον τρόπο κλήσης προσθέτοντας τη δεσμευμένη έκφραση ''(nothrow)'' αμέσως μετά τον τελεστή **new** και να ελέγξουμε την επιστρεφόμενη τιμή ως εξής:
 +
 +<code c++ dynamicMemory.cpp>
 +#include <iostream>
 +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;
 +}
 +</code>
 +
 +===== Παράδειγμα δέσμευσης μνήμης για την αρχικοποίηση ενός διδιάστατου πίνακα =====
 +
 +<code cpp dynamicMemory2D.cpp>
 +#include <iostream>
 +#include <stdlib.h>
 +
 +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<rows; i++) {
 +    array2d[i] = new (nothrow) int[columns];
 +    if(array2d[i] == NULL) {
 +      cerr < "Memory allocation error!\n";
 +      return -1;
 +    }
 +  }
 +  
 +  for(int i=0; i<rows; i++) {
 +    for(int j=0; j<columns; j++) {
 +      array2d[i][j] = i+j;
 +      cout << array2d[i][j] << "  ";
 +    }
 +    cout << endl;
 +  }
 +  
 +  for(int i=0; i<rows; i++) 
 +    delete[] array2d[i];
 +  delete[] array2d;
 +}
 +</code>
 +
  
cpp/dynamic_memory.txt · Last modified: 2021/04/27 05:01 (external edit)