У меня есть некоторые вопросы о векторе в STL для разъяснения.....
Где объекты в векторе выделены? "куча"?
вектор имеет граничную проверку? Если индекс из границы, какая ошибка произойдет?
Почему массив быстрее, чем вектор?
Есть ли какой-либо случай, в котором вектор не применим, но массив - необходимость?
vector
распределяет память так же, как new int [x]
. at
. Он генерирует исключение std :: out_of_range
, если проверка границ завершается неудачно. Оператор []
не выполняет проверку границ. вектор
, если хотите, чтобы ваш контейнер имел динамический размер, и простой массив, если известного фиксированного размера достаточно. Не забудьте проверить другие контейнеры, например deque
и list
, чтобы убедиться, что вы выбрали наиболее подходящий. В противном случае, если вам нужно иметь дело с API, отличными от C ++, вам, очевидно, потребуется доступ к обычному массиву. (править) @BillyONeal говорит, что вы должны использовать & vector [0]
, чтобы получить адрес базового массива, но используйте его с осторожностью, так как он может измениться при изменении емкости вектора. В куче (при условии, что вы используете стандартный распределитель, который используется по умолчанию)
Граница не проверяется при использовании оператора []
, но это если вы используете функцию-член в
(например, my_vec.at (0)
). Если вы используете в
, а индекс находится вне или за пределами, он генерирует исключение std :: out_of_range
.
Массивы обычно не быстрее. Это зависит от того, являются ли вызовы вектора operator []
встроенными или нет. Однако большинству современных компиляторов следует его индексировать, поскольку это всего лишь индекс единственного массива.
В общем случае обычные массивы можно заменить векторами. На самом деле вам не следует использовать std :: vector
в общедоступном интерфейсе библиотеки, а API библиотеки manu требуют необработанных массивов в стиле C.
Где расположены объекты в векторе ? heap?
Это зависит от реализации STL, но, по всей вероятности, в куче, да.
есть ли у вектора проверка границ? Если индекс выходит за границы, какая ошибка произойдет?
Да, вектор растет динамически, вы можете проверить его размер с помощью члена capacity ()
функция. Если ему не хватает места, он обычно выделяет больше места с помощью функции-члена reserve ()
.
Почему массив быстрее вектора?
Массивы могут быть быстрее, потому что это простые данные, к которым не нужно обращаться через объект-оболочку, такой как вектор.
Вы можете представить себе вектор
как аккуратно упакованный массив для вашего удобства.
Есть ли случай, когда вектор неприменим, но массив является обязательным?
Я думаю, могут быть случаи, когда массив предпочтительнее, чем вектор
. Например, при работе с устаревшим кодом C или когда скорость имеет первостепенное значение. Но обычно вы можете решить любую проблему с массивом, поместив данные в вектор STL
.
Объявление 4. При работе с устаревшими интерфейсами (например, POSIX) массивы могут быть необходимыми.
По умолчанию содержимое распределяется динамически. (Но я полагаю, вы можете предоставить распределитель, который получает память из другого места.)
Метод at
выполняет проверки границ и выдает out_of_range
. Другие методы могут проверять или не проверять границы, в зависимости от реализации и настроек.
Я бы предположил, что вектор работает медленнее, чем массив, если он делает что-то отличное от массива. Например, динамическое размещение является дорогостоящим, поэтому у вектора есть стоимость, которой нет у массивов. Динамическое изменение размера вектора является дорогостоящим, в то время как размер массива нельзя изменить вообще. Я бы не ожидал увидеть какую-либо разницу при доступе к элементам (за исключением возможных проверок времени выполнения, выполняемых реализацией, которую вы можете отключить при желании).
Я не знаю такого сценария. Вы всегда можете получить указатель на базовый массив вектора с помощью & vec [0]
. Однако вектор может быть излишним, если вам не нужны какие-либо функции, которые он предоставляет - в основном, возможность (изменять) его размер динамически. В таких случаях с массивом может работать нормально, но обратите внимание, что существуют классы, которые также делают массив объектом первого класса ( std :: tr1 :: array
или boost :: array
]), которые делают массив копируемым и не превращаются в указатель.