Vector elements, size, and room
Traverse safely and distinguish existing elements from reserved storage.
An index must identify an existing element
A size-n vector has element indices 0 through n − 1. operator[] does not promise a C++23 bounds exception. at(i) throws std::out_of_range when the index is outside the size; it does not repair an invalid index. front(), back(), and pop_back() require a nonempty vector.
Container sizes use an unsigned type. Under the source’s length bound of 200000, converting size() to int before subtracting lets a reverse loop start at −1 for empty input. Avoid size() − 1 followed by an unsigned i ≥ 0 condition.
The loop variable decides whether you modify
for (int x : values) reads independent integer copies. Assigning to x does not update the vector. Use int& x for input or modifications, and const auto& when reading larger objects without copying them.
auto copy = values creates an independent vector, while auto& same = values names the existing vector. auto deduces a type; it does not remove the difference between copies and references.
// Complete C++23 program. No input; output: 3 4 5
#include <iostream>
#include <vector>
int main() {
std::vector<int> values{1, 2, 3};
for (int& x : values) x += 2;
for (int i = 0; i < static_cast<int>(values.size()); ++i) {
if (i != 0) std::cout << ' ';
std::cout << values[i];
}
std::cout << '\n';
}Capacity does not grant element access
size() counts elements that exist. capacity() counts how many elements fit without reallocation. reserve(k) requests capacity at least k and leaves size unchanged. resize(k) changes the number of elements; newly added int elements are zero-valued, or use the value supplied to resize(k, value).
clear() removes all vector elements but retains capacity. shrink_to_fit() is a nonbinding request to reduce unused capacity. Exact capacity and growth factors are not promised. Reserving once for a sensible upper count can help; reserve(size() + 1) before every append can interfere with efficient growth.
Container workbench
Insert values, then remove the next accessible item. Priority queue values are shown sorted for explanation, not as an internal heap.
Next removal: 5. Size: 3.
Guided simulation · Change the inputs to test your understanding.
A vector contains 4, 5. After resize(4, 9), then reserve(20), what are its elements?
Turn the idea into code
Predict each printed line: start empty; reserve(5); print size and whether capacity ≥ 5; resize(3, 8); push_back(2); print size and back; resize(2); print size and back; clear(); print empty and whether capacity ≥ 5.
Give me a hint
Track the existing elements separately from allocated room. Check inequalities for capacity rather than a guessed exact value.
Show the explained solution
The lines are 0 1, 4 2, 2 8, and 1 1. Reserve creates no elements. Resize and push create 8 8 8 2; shrinking leaves 8 8. Clear removes those elements and retains capacity.
// Complete C++23 program. No input.
#include <iostream>
#include <vector>
int main() {
std::vector<int> values;
values.reserve(5);
std::cout << values.size() << ' ' << (values.capacity() >= 5) << '\n';
values.resize(3, 8);
values.push_back(2);
std::cout << values.size() << ' ' << values.back() << '\n';
values.resize(2);
std::cout << values.size() << ' ' << values.back() << '\n';
values.clear();
std::cout << values.empty() << ' ' << (values.capacity() >= 5) << '\n';
}Your notes
Mark complete when you can explain it yourself.