В основній пам’яті дані можуть зберігатися двома способами
- пам’ять виділяється або в сегменті стека і залишається закріпленою до завершення виконання конкретної функції, або виділяється в сегменті даних на весь час виконання програми;
- пам’ять виділяється в міру потреби (динамічне виділення пам’яті).
Слід зазначити, що всі приклади, розглянуті раніше, демонструють роботу з даними, які зберігаються першим способом.
Динамічна пам’ять — це вільна пам’ять, у якій під час виконання програми можна виділяти місце залежно від потреб користувача. Доступ до виділених ділянок динамічної пам’яті, що називаються динамічними змінними, здійснюється тільки через покажчики. Час існування динамічних змінних — від початку створення до кінця програми або до явного звільнення пам’яті. У мові 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
Дякую! Це та стаття, яку я шукав!