Используется для значения емкости строки - PullRequest
13 голосов
/ 21 мая 2010

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

Ответы [ 7 ]

10 голосов
/ 21 мая 2010

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

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

6 голосов
/ 21 мая 2010

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

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

Обновление

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

3 голосов
/ 21 мая 2010

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

2 голосов
/ 21 мая 2010

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

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

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

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

2 голосов
/ 21 мая 2010

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

1 голос
/ 22 мая 2010

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

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

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

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

1 голос
/ 21 мая 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...