Урок №90. Динамічні масиви

  Юрій  | 

  Оновл. 12 Січ 2021  | 

 229

Крім динамічного виділення змінних ми також можемо динамічно виділяти і масиви. На відміну від фіксованого масиву, де його розмір повинен бути відомий під час компіляції, динамічне виділення масиву в мові C++ дозволяє нам встановлювати довжину масиву під час виконання програми.

Динамичні масиви

Для виділення динамічного масиву і роботи з ним використовуються окремі форми операторів new і delete: new[] і delete[].

Оскільки ми виділяємо масив, то C++ розуміє, що він повинен використовувати іншу форму оператора new — форму для масиву, а не для змінної. По факту, викликається оператор new[], навіть якщо ми і не вказуємо [] відразу після ключового слова new.

Зверніть увагу, оскільки пам’ять для динамічних і фіксованих масивів виділяється з різних “резервуарів”, то розмір динамічного масиву може бути досить великим. Ви можете запустити вищенаведену програму, але вже виділити масив довжиною 1 000 000 (або, можливо, навіть 100 000 000) елементів без проблем. Спробуйте!

Видалення динамічного масиву

При видаленні динамічних масивів також використовується форма оператора delete для масивів — delete[]. Таким чином, ми повідомляємо процесору, що йому потрібно очистити пам’ять від декількох змінних замість однієї. Найпоширеніша помилка, яку роблять новачки при роботі з динамічним виділенням пам’яті, є використання delete замість delete[] для видалення динамічних масивів. Використання форми оператора delete для змінних при видаленні масиву призведе до таких несподіваних результатів, як пошкодження даних, витік пам’яті, збій або інші проблеми.

Ініціалізація динамічного масиву

Якщо ви хочете ініціалізувати динамічний масив значенням 0, то все досить просто:

До C++11 не було простого способу ініціалізувати динамічний масив ненульовими значеннями (список ініціалізаторів працював тільки з фіксованими масивами). А це означає, що потрібно перебрати кожен елемент масиву і явно присвоїти йому значення:

Трохи стомлює, чи не так?

Однак, починаючи з C++11, з’явилася можливість ініціалізації динамічних масивів через списки ініціалізаторів:

Зверніть увагу, в синтаксисі динамічного масиву між довжиною масиву і списком ініціалізаторів оператора присвоювання (=) немає.

У C++11 фіксовані масиви також можуть бути ініціалізовані з використанням uniform-ініціалізації:

Однак, будьте обережні, так як в C++11 ви не можете ініціалізувати динамічний масив символів рядком C-style:

Замість цього ви можете динамічно виділити std::string (або виділити динамічний масив символів, а потім за допомогою функції strcpy_s() скопіювати вміст потрібного рядка в цей масив).

Також зверніть увагу на те, що динамічні масиви повинні бути оголошені з явним зазначенням їх довжини:

Зміна довжини масиву

Динамічне виділення масивів дозволяє задавати довжину масивів під час операції їх виділення. Однак C++ не надає вбудований спосіб зміни довжини масиву, який вже був виділений. Але і це обмеження можна обійти, динамічно виділивши новий масив, скопіювавши всі елементи зі старого масиву, а потім видаливши старий масив. Однак цей спосіб вразливий до помилок (про це трохи пізніше).

На щастя, в мові C++ є масиви, розмір яких можна змінювати, і називаються вони векторами (std::vector). Про них ми поговоримо на відповідному уроці.

Тест

Напишіть програму, яка:

   запитує у користувача, скільки імен він хоче ввести;

   просить користувача ввести кожне ім’я;

   викликає функцію для сортування імен в алфавітному порядку (ви можете змінити код сортування методом вибору з уроку №80);

   виводить відсортований список імен на екран.

Підказки:

   Використовуйте динамічне виділення std::string для зберігання імен.

   std::string підтримує порівняння рядків за допомогою операторів порівняння < і >.

Приклад результату виконання вашої програми:

How many names would you like to enter? 5
Enter name #1: Jason
Enter name #2: Mark
Enter name #3: Alex
Enter name #4: Chris
Enter name #5: John

Here is your sorted list:
Name #1: Alex
Name #2: Chris
Name #3: Jason
Name #4: John
Name #5: Mark

Відповідь

Оцінити статтю:

1 Зірка2 Зірки3 Зірки4 Зірки5 Зірок (3 оцінок, середня: 5,00 з 5)
Loading...

Залишити відповідь

Ваш E-mail не буде опублікований. Обов'язкові поля відмічені *