Vectors (std::vector)

is the container you'll reach for most in C++: a resizable array that grows on demand, knows its own size, and plugs into the entire standard-algorithm library. This lesson takes you from creating and looping over a vector to sorting, summing, counting, and even building a 2D grid.

Learn Vectors (std::vector) in our free C++ course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick recall.

Part of the free C++ course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

A std::vector is an expandable shelf . You start with a few slots; when you run out, the shelf quietly buys a bigger unit, moves all your books across, and carries on — you never have to measure and order the shelf yourself. A raw array is a fixed bookcase : pick a size once, and if you guess too small you're stuck. The catch with the expandable shelf is that when it moves to a bigger unit, every book changes location — so a sticky note pointing at "third shelf, second slot" (a reference or iterator) may no longer point where you expect after a big growth.

1. Creating & Accessing

Create a vector with brace initialization and read elements by index from 0 . .front() and .back() grab the ends, .size() reports how many elements there are, and .at(i) is the bounds-checked alternative to [i] .

2. Growing & Shrinking

Start with an empty vector and append with push_back ; the vector handles all the memory management for you. pop_back removes the last element, and .empty() tells you whether there's anything left. This dynamic resizing is exactly what raw arrays can't do.

3. Three Ways to Loop

An index loop gives you the position (useful when you need i ). A range-based loop with const auto& reads each element efficiently without copying. A range-based loop with auto& lets you modify elements in place. Reach for the simplest form that does the job.

4. Vectors + Algorithms

The real power of vectors is how well they pair with the standard algorithms. sort orders them, accumulate (from ) sums them, and count_if with a lambda counts matches. Learning to combine a container with these algorithms is the heart of effective C++.

5. 2D Grids: Vector of Vectors

A models a grid or matrix. The constructor builds a rows × cols grid filled with zeros. Index it with two subscripts, grid[r][c] , and loop with nested range-based loops.

Your turn. Build a small list and report on it:

These lines build a vector, sort it, and print the largest value. Reorder so the program prints 9 .

Why: must precede the use of sort . Inside main , you build the vector first, then sort it ascending so the largest value lands at the end — which v.back() reads as 9 . Return and brace close the function.

Predict the output before revealing each answer.

{'vector v = ; v.push_back(4); cout << v.size();'}

4 — three initial elements plus one push_back makes four.

{'vector v = ; sort(v.begin(), v.end()); cout << v[0];'}

1 — after an ascending sort the smallest element is at index 0.

{'vector v = ; for (auto& n : v) n += 1; cout << v[0] << v[1];'}

35 — auto& modifies each element in place, so the vector becomes {' '}.

Compute the high, low, average, and pass count for a vector of grades using the algorithm library. Match the expected output in the comments.

Practice quiz

After vector<int> v = {1, 2, 3}; v.push_back(4); what is v.size()?

  • 3
  • 5
  • 4
  • 0

Answer: 4. Three initial elements plus one push_back makes four. push_back appends to the end and grows the vector as needed.

What is the difference between size() and capacity()?

  • size() is elements stored; capacity() is how many fit before reallocating
  • They are the same
  • capacity() is always 0
  • size() rounds up to a power of two

Answer: size() is elements stored; capacity() is how many fit before reallocating. size() counts the elements actually stored; capacity() is how many it can hold before it must allocate a bigger block and move everything.

What does push_back past the current capacity typically do to capacity?

  • Adds exactly one slot
  • Leaves it unchanged
  • Halves it
  • Roughly doubles it (geometric growth)

Answer: Roughly doubles it (geometric growth). Vectors grow geometrically (commonly doubling), which keeps repeated push_back amortized O(1).

What does v[i] do for an out-of-range index i?

  • Throws std::out_of_range
  • Is undefined behavior (no bounds check)
  • Returns 0
  • Resizes the vector

Answer: Is undefined behavior (no bounds check). operator[] does no bounds checking, so an out-of-range index is undefined behavior. Use at() for a checked access.

What does v.at(i) do that v[i] does not?

  • Bounds-checks and throws std::out_of_range on a bad index
  • Runs faster
  • Sorts the vector
  • Returns a copy

Answer: Bounds-checks and throws std::out_of_range on a bad index. at() checks the index and throws std::out_of_range if it is out of range, while [] does no check.

Why can a pointer or iterator into a vector suddenly become invalid?

  • The vector is const
  • size() was called
  • A reallocation (growth past capacity) moves all elements to new memory
  • It never becomes invalid

Answer: A reallocation (growth past capacity) moves all elements to new memory. When the vector grows past capacity it reallocates, moving elements to a new block, so old pointers, references, and iterators dangle.

After vector<int> e = {2, 4}; for (auto& n : e) n += 1; what does e[0]e[1] print?

  • 24
  • 35
  • 33
  • 46

Answer: 35. auto& binds a reference to each element, so n += 1 modifies in place: the vector becomes {3, 5}, printing 35.

Which is the efficient way to remove the last element of a vector?

  • erase(v.begin())
  • clear()
  • erase(v.end())
  • pop_back() — O(1)

Answer: pop_back() — O(1). pop_back removes the last element in O(1). Erasing from the middle is O(n) because later elements shift down.

What does sort(v.begin(), v.end()) need passed to it?

  • The size
  • A pair of iterators marking the range
  • An index
  • A capacity hint

Answer: A pair of iterators marking the range. Standard algorithms like sort operate on iterator ranges: begin() and end() mark the half-open range to process.

Erasing a single element from the MIDDLE of a vector with erase(it) is what complexity?

  • O(1)
  • O(log n)
  • O(n) because later elements shift down
  • O(n^2)

Answer: O(n) because later elements shift down. erase from the middle is O(n): every element after the removed one shifts down by one position.