В основній пам’яті дані можуть зберігатися двома способами
- пам’ять виділяється або в сегменті стека і залишається закріпленою до завершення виконання конкретної функції, або виділяється в сегменті даних на весь час виконання програми;
- пам’ять виділяється в міру потреби (динамічне виділення пам’яті).
Слід зазначити, що всі приклади, розглянуті раніше, демонструють роботу з даними, які зберігаються першим способом.
Динамічна пам’ять — це вільна пам’ять, у якій під час виконання програми можна виділяти місце залежно від потреб користувача. Доступ до виділених ділянок динамічної пам’яті, що називаються динамічними змінними, здійснюється тільки через покажчики. Час існування динамічних змінних — від початку створення до кінця програми або до явного звільнення пам’яті. У мові C++ застосовують два способи роботи з динамічною пам’яттю. Перший з них дістався в спадщину від мови С і використовує сукупність функцій malloc(), другий — працює з операціями new та delete, які здійснюють динамічний розподіл і скасування з вищим пріоритетом, ніж інші функції.
Оператор new виділяє пам’ять і повертає її адресу. За допомогою оператора delete відбувається звільнення пам’яті, на яку вказує змінна-покажчик.
Загальна форма запису оператора new:
змінна-покажчик = new тип змінної;.
Оператор delete має вигляд:
delete [ ] змінна-покажчик; .
Динамічні масиви створюють за допомогою операції new, при цьому необхідно вказати їх тип і розмірність. Наприклад, Для одновимірного масиву дійсних чисел, що має 100 елементів, треба записати:
int n = 100;
float *р = new float[n]; — змінна-покажчик на float виділяє у динамічній пам’яті ділянку для розміщення 100 елементів дійсного типу.
Слід пам’ятати, що динамічні масиви при створенні не можна ні ініціювати, ні обнуляти.
Приклад 6.16. З використанням динамічної пам’яті обробити вiдомість успішності групи студентів з дисципліни “Програмування” підрахувавши середній бал групи і кількість відмінників.
/* P6_16.CPP использование динамической памяти при обработке одномерного массива */
#include <iostream.h>
#include <conio.h>
#include <math.h>
main ( )
{ const int n = 14; // количество студентов
int *mas; // объявление указателя на массив
int і, k = 0; // k — количество отличников
float s = 0; // s — сумма оценок группы
mas = new int [n]; //выделение динамической памяти
cout << " Ввод оценок " << endl;
for (і = 0; і < n; і++)
сіn >> mas[i];
//---------------- подсчет суммы оценок и количества отличников
for (і = 0; і < n; і++)
{ s = s + mas[i];
if (mas[i] == 5)
k = k+1; }
cout << endl;
cout.precision(3);
cout << "Средний балл = " << s/n << endl;
cout << "Количество отличников = " << k << endl;
getch ();
delete[ ]mas; // освобождение динамической памяти
}
Результати обчислень:
Ввод оценок
33345343245333
Средний балл = 3.43
Количество отличников = 2
У цій програмі змінна s служить для обчислення суми oцiнок групи, а змінна k — для підрахунку кількості відмінників. Перед обчисленням треба надати цим змінним початкове нульове значення (накопичення суми і кількості пояснено у прикладах 1.1-1.2).
При створенні динамічного багатовимірного масиву необхiдно в операції new вказати всі його розмірності (перший може бути змінною), наприклад:
int n = 5; // n — количество строк
int **m = (int **) new int [n][5];.
Розглянемо більш універсальний і безпечний спосіб видiлення динамічної пам’яті під двовимірний масив, коли обидвi йгого розмірностізадаються на етапі виконання програми. Наприклад, розподіл динамічної пам’яті для матриці, що має n рядкiв і m стовпців та елементи цілоготипу, можна здійснити так:
int n, m;
cout << ” Введите количество строк и столбцов: “;
cin >> n >> m;
int **a = new int *[n]; — оголошення змінної тип «покажчи на покажчик на int» і виділення пам’яті для масиву покажчиків на рядки матриці;
for (int і = 0; і < n; і++)
a[і] = new int [m]; — кожному елементу масиву покажчиків на рядки присвоюється адреса початку ділянки пам’яті, виділеної для рядка матриці.
Наочно це представлено на рис. 6.10.

Звільнення пам’яті з-під масиву будь-якої кількості вимірів виконується за допомогою операції delete[].
Приклад 6.17. З використанням динамічної пам’яті створити програму обчислення матриці С за формулою:
С [n][q] = A[n][m] * B[m][q].
Згідно з умовою, елемент матриці C[n][q] дорівнює сумі добутків елементів відповідного рядка матриці A[n][m] на елементи відповідного стовпця матриці
У запропонованій програмі для обчислення елементів добутку матриць організовано три вкладених цикли: цикл переборі рядків матриці А, цикл перебору стовпців матриці В, а також цикл накопичення суми для одержання елемента матриці С. Для виділення динамічної пам’яті під двовимірні масиви A[n][m], B[m][q] і С [n][q] скористаємося розглянутим вищі способом.
/* Р6_17.СРР — использование динамической памяти при работе с матрицами */
#include <iostream.h>
#include <math.h>
#include <conio.h>
main ( )
{ int і, j, k;
int n, m, q;
cout << " Введите размерности матриц: \n";
cout << " n = " ;
cin >> n;
cout << " m = " ;
cin >> m;
cout << " q = " ;
cin >> q;
//----------------- создание динамических массивов
/* выделение динамической памяти под массивы указателей и инициализация массивов указателей */
int **С = new int *[n];
for (int і = 0; і < n; і++)
C[i] = new int [q];
int **A = new int *[n];
for (int і = 0; і < n; i++)
A[i] = new int [m];
int **B = new int *[m];
for (int і = 0; і < m; i++)
B[i] = new int [q];
//------------------------------ ввод матриц A[n][m] и B[m][q]
cout<<"\n Ввод матрицы A[n][m] \n";
for (і = 0; і < n; і++)
for (j = 0; j < m; j++)
сіn >> *(А[i] + j);
cout << "\n Ввод матрицы B[m][q] \n”;
for (i = 0; і < m; i++)
for (j = 0; j < q; j++)
cin >> *(B[i] + j);
//----------------------- вычисление матрицы C[n][q] = A[n][m]*B[m][q]
for (і = 0; і < n; i++) // перебор строк матрицы A[n][m]
for (k = 0; k<q; k++) //перебор столбцов матрицы B[m][q]
{ C[i][k] = 0;
for (j = 0; j < m; j++)
C[i][k] += (A[i][j]* B[j][k]); // определение элемента C[i][k]
}//-------------------- вывод на экран матрицы С[n][q]
cout << "\n Матрица C[n][q] = A[n][m] * B[m][q] \n";
for (і = 0; і < n; i++)
{ for (j = 0; j < q; j++)
cout << *(C[i] + j) << " ";
cout << endl;}
delete [ ]A;
delete [ ]B;
delete [ ]C; // освобождение памяти
getch ();
}
Результати обчислень:
Введите размерности матриц:
n = 4
m = З
q = 5
Ввод матрицы A[n][m]
1 1 1
3 3 3
2 2 2
4 4 4
Ввод матрицы B[m][q]
8 8 8 8 8
7 7 7 7 7
5 5 5 5 5
Матрица C[n][q] = A[n][m] * B[m][q]
20 20 20 20 20
60 60 60 60 60
40 40 40 40 40
80 80 80 80 80
програмування