C++ / CHAPTER 04

Vectors, bounds, and invalidation

Intermediate

Use a growing sequence while respecting its size and changing storage.

By the end of this chapter

  • Iterate over existing elements
  • Distinguish size from reserved capacity
  • Avoid keeping invalidated references

The idea

This chapter assumes loops and function calls. A vector owns an ordered, contiguous collection whose size counts actual elements. push_back creates an additional element. reserve can prepare storage but does not create elements, so reserving ten slots still leaves an empty vector empty. Use a range-based loop when you only need each value, or an index that remains strictly below size when positions matter.

Growth may move the vector’s storage. If insertion causes reallocation, references, pointers, and iterators into the old storage become invalid. Do not keep an element reference across an operation that might reallocate and then read it. Reacquire the element afterward, or retain a logical index when that index still identifies the intended element. at offers checked access; unchecked subscripting requires your own bounds reasoning.

C++ example
#include <iostream>
#include <vector>
int main(){
  std::vector<int> jobs{3,5};
  jobs.push_back(7);
  int total=0;
  for(int job:jobs) total+=job;
  std::cout<<jobs.size()<<" "<<total<<"\n";
}
Result
3 15

The vector contains three initialized elements. The loop visits exactly those elements; neither capacity nor an extra end position contributes a value.

Try it yourself

Build a vector of even values from another vector without changing the input.

Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.

CHECK YOUR UNDERSTANDING

Chapter checkpoint

After std::vector<int> v; v.reserve(8); what is v.size()?