Вы можете объявить вектор следующим образом:
std::vector<int> v;
Это пустой vector
из int
с именем v
. Имеет 0 элементов. Попытка получить доступ к любому из его элементов - неопределенное поведение. Так что да, возможно создать переполнение буфера в std::vector
, если вы плохо к нему относитесь.
v[0] = 1; // undefined because we're out of bounds
v[1] = 2; // as is this
Обычно при добавлении элементов к std::vector
вы используете push_back
или emplace_back
, однако не прямой доступ к элементу
v.push_back(0); // v is now 1 element long: { 0 }
v.emplace_back(1); // v is now 2 elements long: { 0 , 1 }
Использование оператора []
дает ссылку на базовый элемент, поэтому вы можете использовать его как для поиска, так и для назначения, если как вы уверены, что индекс действителен. Вы можете использовать функцию size()
, чтобы определить соответствующий индекс максимального элемента (это size() - 1
)
for (std::size_t i = 0; i < v.size(); ++i)
{
v[i] = 10;
}
// v was size 2, we've replaced both elements at 0 and 1 with value 10
При использовании std::vector
используйте предоставленный вам интерфейс. Используйте push_back
или emplace_back
или insert
для добавления элементов. pop_back
или erase
для удаления элементов. A std::vector
знает его begin
и end
, поэтому вы можете выполнить итерацию по нему следующим образом:
// prints the elements in the vector
for (auto it = v.begin(); it != v.end(); ++it)
std::cout << *it << " ";
std::cout << "\n";
или на основе ранжирования для l oop, поскольку он обеспечивает begin()
и end()
функции
// prints the elements in the vector
for (const auto& elem : v)
std::cout << elem << " ";
std::cout << "\n";
Возможно переполнение буфера std::vector
, но очень маловероятно, если вы будете следовать правилам. std::vector
лучше, чем массив, поэтому, если вы не возражаете против ваших элементов, существующих в бесплатном хранилище (которое является большинством не высокопроизводительных приложений), go для него. Простота использования и гибкость оправдывают дополнительные издержки.
Более того, поскольку данные в вашем std::vector
НЕ существуют в стеке (в то время как локальный массив помещается в стек), вы очень вряд ли перезапишет ваш стек, если вы переполните свой std::vector
. Если вам повезет, ваша программа обработает sh, но не полагайтесь на это.
В заключение, std::vector
может иметь переполнение буфера, но его интерфейс делает его очень трудным для выполнения так. Если вы когда-нибудь переполните его буфер, вы перезаписываете данные в бесплатном хранилище, а не в стеке, поэтому вы не будете изменять свой обратный адрес. Несмотря на то, что второй элемент в бесплатном хранилище потенциально может быть перезаписан переполнением буфера vector
, я считаю, что это не является детерминированным c. Хотя любой, у кого есть доступ к вашему исходному коду с массивом, может легко определить, какой ввод приведет к перезаписи стека, если таковой имеется.
См. https://en.cppreference.com/w/cpp/container/vector для получения дополнительной информации об интерфейсе std::vector
.