C++/Zarządzanie pamięcią: Różnice pomiędzy wersjami

Z Wikibooks, biblioteki wolnych podręczników.
< C++
Usunięta treść Dodana treść
Derbeth (dyskusja | edycje)
m język
poprawka w kodzie
Linia 4: Linia 4:
<pre class="lang-cpp">
<pre class="lang-cpp">
int *Wektor = (int*)malloc(sizeof(int)*10);
int *Wektor = (int*)malloc(sizeof(int)*10);
free(Wektor);
free(Wektor);</pre>
albo w stylu C++:
Albo w stylu C++:
<pre class="lang-cpp">
int *Wektor = new int[10];
int *Wektor = new int[10];
delete Wektor;
delete Wektor;

Wersja z 18:34, 16 gru 2006

W języku C++ do alokowania pamięci służy operator new a do zwalniania - delete. W C++ można również stosować funkcje malloc i free, jednak należy być ostrożnym. Najczęstszym błędem jest mieszanie operatorów new i delete z funkcjami malloc i free , np. zwalnianie pamięci zaalokowanej przez new przy pomocy free.

Rozważmy prosty przykład. Załóżmy, że chcemy stworzyć wektor 10 liczb typu całkowitego. Możemy to zrobić na dwa sposoby.W stylu znanym z języka C:

int *Wektor = (int*)malloc(sizeof(int)*10);
free(Wektor);

Albo w stylu C++:

int *Wektor = new int[10];
delete Wektor;


Od razu widać, że drugi zapis jest zdecydowanie łatwiejszy i przyjemniejszy w użyciu. To jest podstawowa zaleta operatora new - krótszy zapis. Wystarczy wiedzieć jakiego typu ma być obiekt, który chcemy powołać do życia, nie martwiąc się o rozmiar alokowanego bloku pamięci. Za pomocą operatora new można również tworzyć tablice wielowymiarowe:

int **Wektory = new int *[5];
for( int i=0; i<5; i++ )
   Wektory[i] = new int [10];

W ten sposób stworzono tablicę dwuwymiarową którą statycznie zadeklarowalibyśmy jako:

int Wektory[5][10];


Ilość elementów poszczególnych wymiarów nie musi być jednakowa. Można np zadeklarować tablicę taką:

int **Wektory = new int *[2];
Wektory[0] = new int [5];
Wektory[1] = new int;


Przy takiej deklaracji pierwszy wiersz ma 5 elementów (tablica) a drugi to jeden element. Deklaracja tablic o większej ilości wymiarów przebiega podobnie:

int ***Wektory = NULL;      // deklarujemy tablicę 3-wymiarową
Wektory = = new int **[5];  // pierwszy wymiar
Wektory[0] = new int *[10]; // pierwszy element pierwszego wymiaru
Wektory[1] = new int *[3];  // drugi element pierwszego wymiaru
....
Wektory[0][1] = new int [3] // wymiar I = 0 -> wymiar II = 1 -> 3 elementy(tablica)
Wektory[0][3] = new int [5] // wymiar I = 0 -> wymiar II = 3 -> 5 elementów(tablica)
Wektory[1][2] = new int;    // wymiar I = 1 -> wymiar II = 2 -> 1 element
...


Stosując ten algorytm ogólnie można deklarować tablice n-wymiarowe bez większego problemu. Usuwanie tablic wielowymiarowych przebiega podobnie jak jednowymiarowych z tą różnicą, że usuwanie zaczynamy od "najgłębszego" wymiaru:

int ***Wektory = new int **[2];
Wektory[0] = new int *[2];
Wektory[1] = new int *[2];
Wektory[0][0] = new int;     // pojedyńcza zmienna dynamniczna! nie tablica
Wektory[0][1] = new int [5]; // zmienna tablicowa
Wektory[1][0] = new int [3];   
Wektory[1][1] = new int [2];
...
// Kod programu
...
// III wymiar
delete Wektory[0][0];        // kasujemy pojedyńczą zmienną
delete [] Wektory[0][1];
delete [] Wektory[1][0];
delete [] Wektory[1][1];
// II wymiar
delete [] Wektory[0];
delete [] Wektory[1];
// I wymiar
delete [] Wektory;

Zwrócić uwagę trzeba na dwie rzeczy:

  1. delete [] używamy dla zmiennych tablicowych a delete dla pojedyńczych zmiennych
  2. Kolejność zwalniania wymiarów jest odwrotna niż ich tworzenia


Drugą zaletą jest fakt, że przy okazji alokacji pamięci możemy wywołać odpowiedni konstruktor inicjalizując wartości zmiennych obiektu, np.

Test *Test = new Test(1,2);

zakładając, że obiekt Test posiada dwie zmienne typu całkowitego i zdefiniowany konstruktor Test(int,int).

Kolejną korzyścią jest możliwość przeciążania. Jednak to już jest temat na inny rozdział.

Szablon:ProstaNawigacja