Урок №202. Длина и ёмкость std::string

  Юрий  | 

  Обновл. 24 Авг 2020  | 

 16941

 ǀ   2 

При создании строки не помешало бы указать её длину и ёмкость (или хотя бы знать эти параметры).

Длина std::string

Длина строки — это количество символов, которые она содержит. Есть две идентичные функции для определения длины строки:

   size_type string::length() const

   size_type string::size() const

Обе эти функции возвращают текущее количество символов, которые содержит строка, исключая нуль-терминатор. Например:

Результат:

6

Хотя также можно использовать функцию length() для определения того, содержит ли строка какие-либо символы или нет, эффективнее использовать функцию empty():

   bool string::empty() const — эта функция возвращает true, если в строке нет символов и false — в противном случае.

Например:

Результат:

false
true

Есть еще одна функция, связанная с длиной строки, которую вы, вероятно, никогда не будете использовать, но мы все равно её рассмотрим:

   size_type string::max_size() const — эта функция возвращает максимальное количество символов, которое может хранить строка. Это значение может варьироваться в зависимости от операционной системы и архитектуры операционной системы.

Например:

Результат:

2147483647

Ёмкость std::string


Ёмкость строки — это максимальный объем памяти, выделенный строке для хранения содержимого. Это значение измеряется в символах строки, исключая нуль-терминатор. Например, строка с ёмкостью 8 может содержать 8 символов.

   size_type string::capacity() const — эта функция возвращает количество символов, которое может хранить строка без дополнительного перераспределения/перевыделения памяти.

Например:

Результат:

Length: 10
Capacity: 15

Примечание: Запускать эту и следующие программы следует в полноценных IDE, а не в веб-компиляторах.

Обратите внимание, ёмкость строки больше её длины! Хотя длина нашей строки равна 10, памяти для неё выделено аж на 15 символов! Почему так?

Здесь важно понимать, что, если пользователь захочет поместить в строку больше символов, чем она может вместить, строка будет перераспределена и, соответственно, ёмкость будет больше. Например, если строка имеет длину и ёмкость равную 10, то добавление новых символов в строку приведет к её перераспределению. Делая ёмкость строки больше её длины, мы предоставляем пользователю некоторое буферное пространство для расширения строки (добавление новых символов).

Но в перераспределении есть также несколько нюансов:

   Во-первых, это сравнительно ресурсозатратно. Сначала должна быть выделена новая память. Затем каждый символ строки копируется в новую память. Если строка большая, то тратится много времени. Наконец, старая память должна быть удалена/освобождена. Если вы делаете много перераспределений, то этот процесс может значительно снизить производительность вашей программы.

   Во-вторых, всякий раз, когда строка перераспределяется, её содержимое получает новый адрес памяти. Это означает, что все текущие ссылки, указатели и итераторы строки становятся недействительными!

Обратите внимание, не всегда строки создаются с ёмкостью, превышающей её длину. Рассмотрим следующую программу:

Результат:

Length: 15
Capacity: 15

Примечание: Результаты могут отличаться в зависимости от компилятора.

Теперь давайте добавим еще один символ в конец строки и посмотрим на изменение её ёмкости:

Результат:

Length: 15
Capacity: 15
Length: 16
Capacity: 31

Есть еще одна функция (а точнее 2 варианта этой функции) для работы с ёмкостью строки:

   void string::reserve(size_type unSize) — при вызове этой функции мы устанавливаем ёмкость строки равную как минимум unSize (она может быть и больше). Обратите внимание, для выполнения этой функции может потребоваться перераспределение.

   void string::reserve() — если вызывается эта функция или вышеприведенная функция с unSize меньше текущей ёмкости, то компилятор попытается срезать (уменьшить) ёмкость строки до соответствия её длины. Это необязательный запрос.

Например:

Результат:

Length: 10
Capacity: 15
Length: 10
Capacity: 303
Length: 10
Capacity: 303

Здесь мы можем наблюдать две интересные вещи. Во-первых, хотя мы запросили ёмкость равную 300, мы фактически получили 303. Ёмкость всегда будет не меньше, чем мы запрашиваем (но может быть и больше). Затем мы запрашиваем изменение ёмкости в соответствии со строкой. Этот запрос игнорируется, так как ёмкость не изменилась.

Если вы заранее знаете, что вам нужна строка побольше, так как вы будете выполнять с ней множество операций, которые потенциально могут увеличить её длину или ёмкость, то вы можете избежать перераспределений, сразу установив строке её окончательную емкость:

Результат этой программы будет меняться при каждом её новом запуске:

tregsxxmselsqlfoahsvsxfmfwurcmmjclfcqqgzkzohztirriibtoibucswaudyirkvjbwxfysoqzcc

Вместо того, чтобы перераспределять sString несколько раз, мы устанавливаем её ёмкость один раз, а затем просто заполняем данными.

Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (51 оценок, среднее: 4,96 из 5)
Загрузка...

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

  1. Аватар Кашпировский:

    Если писать строку более 195 Идет ошибка Out of range — Ну я не знаю что делать ?

    1. Аватар Пётр:

      Вы делаете массив стрингов и после пытаетесь к массиву применить метод, надо применять к элементу массива тогда уж. Полный код приводите, а то непонятно вообще, что вы хотите.

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

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