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

  Юрий  | 

  Обновл. 2 Июл 2019  | 

 2863

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

Длина 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 (19 оценок, среднее: 5,00 из 5)
Загрузка...

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

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

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