Урок №95. Введение в std::vector

  Юрий  | 

  Обновл. 28 мая 2019  | 

 24014

 ǀ   13 

В предыдущем уроке мы рассматривали 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 (129 оценок, среднее: 4,86 из 5)
Загрузка...

Комментариев: 13

  1. Аватар Игорь:

    Доброго времени суток!
    В этой статье нет ни слова про дву-х, трё-х, *N — мерные векторы и массивы пространства имён std. Подозреваю что можно реализовать аналогично указателю на указатель (древовидная структура) массив в массиве, но надеюсь есть способ проще и удобней. Конечно сам доберусь до этого, но надеюсь получить ответ и возможно мой вопрос поможет улучшить/дополнить 95-й урок.

  2. Аватар Oleh:

    Что означает здесь оператор (:)?

    1. Аватар Анастасия:

      это синтаксис цикла foreach, означает что element является элементом упорядоченной структуры (массива).

  3. Аватар Alexey:

    Отличные статьи, но очень плохо, что в этой не сказано про такую полезную вещь, как добавление элемента в конец вектора:

    После этого 25 добавится в конец вектора v.

  4. Аватар Andrey:

    Отличный слог, легко читается. Спасибо.

    P.S. Немного знаком с синтаксисами других языков, и когда читал про в Ваших статьях про стандартные массивы CPP, был озадачен. Оказалось что есть нормальные решения. Можно не только на счетах работать. 🙂

  5. Аватар Новичок:

    Спасибо Вам огромное! Буду с нетерпением ждать!

    1. Юрий Юрий:

      Спасибо и Вам 🙂

  6. Аватар Новичок:

    А когда будет продолжение? Просто очень хочется учится дальше!

    1. Юрий Юрий:

      На этой неделе постараюсь две-три статьи опубликовать. Просто сейчас времени мало, сессия скоро.

  7. Хочу пройти ваш курс по c++, после всех уроков какой уровень знаний у меня будет?Я выучу весь c++?

    1. Юрий Юрий:

      Вы поймёте всё необходимое для программирования на языке С++.

  8. Аватар Zufar:

    Продолжай , всё доступно и понятно! Спасибо за уроки!

    1. Юрий Юрий:

      Спасибо, буду продолжать.

Добавить комментарий

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

telegram канал
НОВОСТИ RAVESLI