C++ Vectors
std::vector, from the vector header, is the most used container in C++. It works like an array that grows and shrinks as needed, knows its size and frees its memory automatically.
Creating and adding
#include <iostream>
#include <vector>
int main() {
std::vector<int> scores = {78, 85, 62};
scores.push_back(90); // add at the end
scores.push_back(74);
std::cout << "size " << scores.size() << "\n";
std::cout << "first " << scores.front() << ", last " << scores.back() << "\n";
scores.pop_back(); // remove the last
std::cout << "after pop_back: " << scores.size() << "\n";
std::vector<double> zeros(4); // four zeros
std::vector<char> stars(3, '*'); // three stars
std::cout << zeros.size() << " " << stars[0] << stars[1] << stars[2] << "\n";
return 0;
}size 5 first 78, last 74 after pop_back: 4 4 ***
Reaching elements
v[i] reads element i without checking; v.at(i) checks and throws std::out_of_range when i is outside the vector. Use at while learning, or turn on Safe mode, which stops a v[i] outside the vector.
Looping
#include <iostream>
#include <vector>
int main() {
std::vector<int> marks = {78, 85, 62, 90, 74};
int total = 0;
for (int m : marks) total += m;
std::cout << "average " << static_cast<double>(total) / marks.size() << "\n";
for (int& m : marks) m += 5; // change every element
for (std::size_t i = 0; i < marks.size(); i++) {
std::cout << i << ":" << marks[i] << " ";
}
std::cout << "\n";
return 0;
}average 77.8 0:83 1:90 2:67 3:95 4:79
Inserting and erasing
insert and erase take a position given as an iterator: v.begin() + i is the position of element i (see Iterators).
#include <iostream>
#include <vector>
int main() {
std::vector<int> v = {10, 20, 30, 40};
v.insert(v.begin() + 1, 15); // before element 1
v.erase(v.begin() + 3); // remove element 3 (the 30)
for (int x : v) std::cout << x << " ";
std::cout << "\n";
v.clear();
std::cout << std::boolalpha << v.empty() << "\n";
return 0;
}10 15 20 40 true
Inserting or erasing in the middle moves all later elements, so it is slow for long vectors; adding and removing at the end is fast.
Two dimensions
A vector of vectors makes a table whose rows can even have different lengths:
#include <iostream>
#include <vector>
int main() {
std::vector<std::vector<int>> grid(3, std::vector<int>(4, 0)); // 3 rows of 4 zeros
grid[1][2] = 7;
for (const auto& row : grid) {
for (int x : row) std::cout << x << " ";
std::cout << "\n";
}
return 0;
}0 0 0 0 0 0 7 0 0 0 0 0
Performance tip
A vector grows by reserving a bigger block and moving its elements. When you know roughly how many elements will come, v.reserve(n) reserves the room once. Pass vectors to functions by const& to avoid copying them.
Common mistakes
v[i]does not check the index; reading past the end is undefined behaviour. Usev.at(i)while learning, it throwsstd::out_of_rangeinstead.size()is unsigned, sov.size() - 1on an empty vector becomes a huge number. Checkv.empty()first.- Adding elements can move the whole vector to new memory, which makes pointers, references and iterators to its elements invalid.
Practice exercises
- Read numbers until 0 into a vector and print them in reverse.
- Remove all negative numbers from a vector (hint: build a new vector, or see
std::erase_ifin C++20). - Store a 3 by 3 table in a vector of vectors and print each row's sum.