Accessing Vector Elements
push_back() adds one element at the end of a vector and increases its size by one.
A Vector That Grows While the Program Runs
A vector does not have to keep the number of elements it started with. Its size can change while the program runs, and one of the most useful operations for changing it is push_back(). Before reading on, keep one question in mind: when new values arrive, where does each one end up, and how does the size change after each one?
What do you think happens?
A vector holds 10 and then 20. You call push_back(7). What is at index 0, and what is size() afterward?
Reveal answer
10 is still at index 0 and size() is 3
push_back() attaches the new element after every existing element. The existing elements do not move, so 10 stays at index 0, 20 stays at index 1, and 7 lands at index 2. The count goes from 2 to 3.
Appending Elements with push_back()
push_back() adds one element at the end of a vector and increases its size by one.
Two facts follow from this definition. First, the position of the new element is fixed: it goes at the end, after every element that was already there. Second, the operation is cumulative. Each call adds exactly one element, so a vector that receives several push_back() calls grows by one for each call. The initial size is not permanent; push_back() is one of the most useful ways to change it.
2
3- v starts empty, so its size is 0 before the first call.
- Each
push_back()call adds one element at the end. - The second cout reports 3 because the call with 7 added one more element.
How the Input Loop Decides to Stop
Many programs fill a vector from standard input rather than from values written in the code. The source pattern reads values into a variable e and calls push_back() on each one that is read successfully. The loop header has no counter and no explicit end condition. Its test is the read itself: cin >> e is evaluated on each pass, and the loop body runs only while that read succeeds.
- The header has no counter and no increment; the test is the read cin >> e.
- The body runs once for each value read successfully.
- When the read fails at end of input or on a format error, the loop stops and the size reflects the successful reads.
Subscripting with a Zero-Based Index
Each element in a vector has a position number called its index. Writing the vector's name followed by the index in square brackets selects that element. Indexing starts at 0, so v[0] holds the first element, v[1] holds the second, and so on.
The index is just a value, so it can be a variable. When i takes the values 0, 1, and 2 in turn, v[i] selects a different element on each pass. This is the mechanism that index-based loops depend on. Subscripting returns a stored value, and the index says which stored value to return.
Reading Elements and Counting Them
A vector holds 10, 20, and 30 in that order. What does the program print for v[0], v[2], and v.size()?
- 1Identify index 0
v[0] selects the first element, which is 10.
- 2Identify index 2
The vector has three elements, so the valid indexes are 0, 1, and 2. v[2] selects the third element, which is 30.
- 3Count the elements
size()returns how many elements the vector holds, which is 3. It returns a count, not an element.
The program prints 10, then 30, then 3.
10
30
3- v[0] is the first element.
- v[2] is the last element because the valid indexes end at
size()minus 1. v.size()is a count of three elements, not an element value.
Counting Elements with size()
The member function size() gives the number of elements in a vector. You call it with a dot after the vector's name, as in book.size(). The result is a count, not an element. This is the distinction that matters most here: subscripting returns a stored value, while size() returns how many values are stored.
Looping Over Every Element
A loop can visit every element by using an index that runs from 0 up to, but not including, the size. The code below is a simplified illustration written for this article, using a vector of int so each step can be checked directly. The loop variable i takes the values 0, 1, 2 and so on, and the condition compares i with v.size(). The loop therefore visits every element exactly once and then stops, and it adapts automatically when the vector holds a different number of elements.
#include <iostream>
#include <vector>
using namespace std;
void print_values(const vector<int>& v) {
for (int i = 0; i < v.size(); ++i) {
cout << v[i] << endl;
}
}- 1The function takes the vector by reference so it reads the caller's vector without copying it.
- 2The counter i starts at 0, which is the first valid index.
- 3The condition i <
v.size()keeps the loop going while the index is still a valid position. - 4The body prints v[i], so each pass selects the next element in order.
The range-for form does the same job with less bookkeeping. It names each element directly, so there is no counter to start, compare, or increment. The reference const auto& names each element without copying it.
- The loop header names no index and no size.
- x takes each element in order, so the body runs once per element.
Mistakes with Indexes and push_back()
Most subscripting errors come from forgetting that counting starts at 0, or from confusing the count with an element. The mistakes below follow directly from those two rules.
Common mistake Treating size() as the last valid index
What it looks likev[v.size()] on a three-element vectorWhy it failsIndexes run from 0 to
size()minus 1, so a three-element vector has no index 3.Do this insteadUse v[v.size() - 1] to reach the last element.
Common mistake Starting an index loop at 1 or running it up to the size
What it looks likefor (int i = 1; i <= v.size(); ++i)Why it failsStarting at 1 skips v[0], and the <= test reaches v[
size()], which is past the end.Do this insteadStart at i = 0 and continue while i < v.size().Common mistake Expecting push_back() to insert at the front
What it looks likeCalling push_back(7) on a vector holding 10 and 20 and expecting 7 at index 0
Why it failspush_back()adds the new element at the end, after every existing element. Existing positions do not move.Do this insteadAfter the call the vector is 10, 20, 7, and 7 is at index 2.
Common mistake Assuming the size stays at the starting value
Why it failsThe size can change while the program runs, and each
push_back()call increases it by one.Do this insteadTrack the size after each call, or call size() when you need the current count.
Common mistake Using the contents of a vector as its count
Why it failssize()returns how many elements exist, not the value of any element.
Predicting a Vector's Contents
A program starts with an empty vector of int. It calls push_back() with 7, then with 4, then with 9. It then prints v[1] and v.size(). Predict the two values printed and the final contents of the vector.
Hints
- After the three calls the vector holds 7, 4, 9 in that order, so the size is 3.
- Index 1 is the second element, not the first.
size()returns a count of elements, so it is not the same as any element's value.
Key Takeaways
push_back()adds one element at the end of a vector and increases its size by exactly one, leaving existing elements in place.- An input loop built on cin >> e and
push_back()stops when a read reaches the end of input or hits a format error, and the vector keeps the elements appended before that point. - Elements are accessed by subscripting with an index that starts at 0, so v[0] is the first element and the last valid index is
size()minus 1. size()returns how many elements the vector holds, which is a count rather than an element value.- A range-for loop such as for (const auto& x : v) visits every element in order without using an index.