Урок №99. Введення в std::vector

  Юрій  | 

  Оновл. 26 Сер 2021  | 

 269

На попередньому уроці ми розглядали std::array, який є безпечнішою і зручнішою формою звичайних фіксованих масивів в мові C++. Аналогічно, в Стандартній бібліотеці C++ є поліпшена версія динамічних масивів (безпечніша і зручніша) — std::vector.

На відміну від std::array, який недалеко відійшов від базового функціоналу звичайних фіксованих масивів, std::vector поставляється з додатковими можливостями, які роблять його одним з найбільш корисних і універсальних інструментів в мові C++.

Вектори

Представлений в C++03, std::vector (або просто “вектор”) — це той же динамічний масив, але який може сам керувати виділеною йому пам’яттю. Це означає, що ви можете створювати масиви, довжина яких задається під час виконання, без використання операторів new і delete (явної вказівки на виділення і звільнення пам’яті). std::vector знаходиться в заголовку vector. Оголошення std::vector наступне:

Зверніть увагу, що як і в неініціалізованому, так і в ініціалізованому випадках вам не потрібно явно вказувати довжину масивів. Це пов’язано з тим, що std::vector динамічно виділяє пам’ять для свого вмісту за запитом.

Подібно std::array, доступ до елементів масиву може виконуватися як через оператор [] (який не виконує перевірку діапазону), так і через функцію at() (яка виконує перевірку діапазону):

У будь-якому випадку, якщо ви будете надавати запит на елемент, який знаходиться поза діапазоном array, довжина вектора автоматично змінюватися не буде. Починаючи з C++11, ви також можете присвоювати значення для std::vector, використовуючи список ініціалізаторів:

В такому випадку вектор самостійно змінюватиме свою довжину, щоб відповідати кількості наданих елементів.

Скажи “Ні!” витокам пам’яті!

Коли змінна-вектор виходить з області видимості, вона автоматично звільняє пам’ять, яку контролювала (займала). Це не тільки зручно (так як вам не потрібно це робити вручну), але також допомагає запобігти витокам пам’яті. Розглянемо наступний фрагмент:

Якщо змінній value присвоїти значення true, то array ніколи не буде видалений, пам’ять ніколи не буде звільнена і станеться витік пам’яті.

Однак, якби array був вектором, то подібне ніколи б і не сталося, оскільки пам’ять звільнялася б автоматично при виході array з області видимості (незалежно від того, чи вийде функція раніше з області видимості чи ні). Саме через це використання std::vector є безпечнішим, ніж динамічне виділення пам’яті через оператор new.

Довжина векторів

На відміну від стандартних динамічних масивів, які не знають свою довжину, std::vector свою довжину запам’ятовує. Щоб її дізнатися, потрібно використати функцію size():

Результат:

The length is: 7

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

Результат:

The length is: 7
0 1 2 0 0 0 0

Тут є дві речі, на які слід звернути увагу. По-перше, коли ми змінили довжину array, існуючі значення елементів збереглися! По-друге, нові елементи були ініціалізовані значенням за замовчуванням у відповідність з певним типом даних (значенням 0 для типу int).

Довжину вектора також можна змінити і в зворотний бік (обрізати):

Результат:

The length is: 4
0 1 4 7

Зміна довжини вектора є витратною операцією, тому рекомендується мінімізувати кількість подібних виконуваних операцій.

Висновки

Це вступна стаття, призначена для ознайомлення з основами std::vector. На наступних уроках ми детально розглянемо std::vector, в тому числі і різницю між довжиною і ємністю вектора, і те, як в std::vector виконується виділення пам’яті.

Оскільки змінні типу std::vector можуть самі керувати виділеною їм пам’яттю (що допомагає запобігти витокам пам’яті), відстежують свою довжину і легко її змінюють, то рекомендується використовувати std::vector замість стандартних динамічних масивів.

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

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

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

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