Используется для значения емкости строки

В стандартной библиотеке С++ std::string имеется функция открытого участника capacity(), которая возвращает размер внутренней выделенной памяти, значение, большее или равное количеству символов в строке (согласно здесь). Для чего это значение можно использовать? Имеет ли он какое-то отношение к пользовательским распределителям?

Ответы

Ответ 1

Скорее всего, вы будете использовать функцию члена reserve(), которая устанавливает емкость как минимум для поставляемого значения.

Сама функция члена capacity() может использоваться, чтобы избежать выделения памяти. Например, вы можете перерабатывать использованные строки через пул и помещать их в ведро различного размера на основе его емкости. Клиент пула может запросить строку, которая уже имеет минимальную емкость.

Ответ 2

Функция string::capacity() возвращает количество общих символов, которое может содержать std::string, прежде чем перераспределять память, что является довольно дорогостоящей операцией.

A std::vector работает таким же образом, поэтому я предлагаю вам посмотреть std::vector здесь для подробного объяснения разницы между выделенной и инициализированной памятью.

Обновление

Хм, я вижу, что я неправильно понял вопрос, на самом деле, я думаю, что я никогда не использовал capacity() самостоятельно ни на std::string, ни на std::vector, по всей видимости, редко бывает какой-либо причины, так как вам все равно нужно резервировать.

Ответ 3

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

Ответ 4

Он может использоваться для некоторой настройки производительности, если вы собираетесь добавить много символов в строку. Перед запуском манипуляции с строкой вы можете проверить емкость и, если она слишком мала, reserve желаемую длину за один шаг ( вместо того, чтобы позволить ему перераспределять последовательно более крупные куски памяти несколько раз, что было бы продуктивным свиноматом).

Ответ 5

Строки имеют емкость и размер. Емкость указывает, сколько символов, которые может содержать строка, прежде чем ей придется выделять больше памяти. Размер указывает количество символов, которые он в настоящее время удерживает. reserve() можно использовать для установки минимальной емкости строки (она будет выделять память хотя бы на то количество символов, но может выделить больше).

Это в первую очередь важно, если вы увеличиваете размер строки. Когда вы присоединяетесь к строке с помощью += или append(), символы из данной строки будут добавлены в конец текущей. Если увеличение строки до этого размера не превышает емкость, тогда она просто будет использовать емкость, которая у нее есть. Однако, если новый размер превысит текущую емкость, тогда строка должна будет перераспределить внутреннюю память и скопировать ее внутренности в новую память. Если вы собираетесь делать это много, это может стать дорогостоящим (хотя это делается в амортизированном постоянном времени), поэтому в таком случае вы можете использовать reserve() для предопределения достаточной памяти, чтобы уменьшить частоту перераспределения имеют место.

векторные функции в основном одинаковы с теми же функциями.

Лично, хотя время от времени я имел дело с capacity() и reserve() с вектором, я никогда не видел необходимости делать это со строкой - возможно, потому, что обычно не хватает конкатенаций строк в мой код, чтобы он того стоил. В большинстве случаев конкретная строка может получить несколько конкатенаций, но недостаточно, чтобы беспокоиться о ее емкости. Беспокойство по поводу производительности, как правило, вы делаете, пытаясь оптимизировать свой код.

Ответ 6

Вряд ли есть какое-либо соответствующее использование. Он похож на std::vector:: емкость. Однако одним из наиболее распространенных применений строк является присвоение. При назначении std::string его емкость может измениться. Это означает, что реализация имеет право игнорировать старую емкость и выделять достаточно памяти.

Ответ 7

Он действительно не очень полезен и, вероятно, существует только для симметрии с vector (в предположении, что оба будут работать внутренне таким же образом).

Емкость вектора гарантированно влияет на поведение изменения размера. Изменение размера вектора на значение, меньшее или равное емкости, не приведет к перераспределению и поэтому не приведет к аннулированию итераторов или указателей, ссылающихся на элементы в векторе. Это означает, что вы можете предварительно выделить некоторое хранилище, вызвав резерв на вектор, затем (с осторожностью) добавить к нему элементы путем изменения размера или отталкивания назад (и т.д.), С уверенностью в том, что базовый буфер не будет перемещаться.

Нет никакой гарантии для string. Кажется, что емкость предназначена только для информационных целей - хотя даже это растягивается, так как в любом случае нет никакой полезной информации. (Хуже того, смежность строковых символов также не гарантируется, поэтому единственный способ получить строку в виде линейного буфера - c_str() - что может вызвать перераспределение.)

Предполагалось, что string предположительно изначально предназначалось для реализации как своего рода частный случай vector, но со временем они разошлись...