Introduction
An array in C has a fixed size, and it forgets how long it is. std::vector fixes both problems: it grows when you add to it, it knows its size, and it frees its own memory. In modern C++, it should be your first choice for a list.
How it works
| Code | Effect |
|---|---|
vector<int> v; | an empty vector |
vector<int> v(5, 0); | five zeros |
v.push_back(x) | adds at the end |
v.pop_back() | removes the last element |
v.size(), v.empty() | its length; whether it is empty |
v[i], v.at(i) | an element, unchecked or checked |
v.front(), v.back() | the first and last elements |
v.insert(v.begin() + i, x) | inserts at a position |
v.erase(v.begin() + i) | removes at a position |
Range-based for visits each element: for (int x : v). Use for (int& x : v) to change them, and const auto& for large elements.
Bad indexes. v[10] on a smaller vector is not checked, and its behaviour is undefined. v.at(10) throws an exception instead.
Sorting uses the <algorithm> header: sort(v.begin(), v.end());.
Tables are vectors of vectors:
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<vector<int>> grid(2, vector<int>(3, 0));
grid[1][2] = 7;
for (const vector<int>& row : grid) {
for (int x : row) {
cout << x << " ";
}
cout << endl;
}
return 0;
}Inserting and erasing in the middle must move every later element, so they are slow on long vectors. Adding and removing at the end is fast.
Syntax
vector<int> v = {3, 1, 2};
v.push_back(5);
sort(v.begin(), v.end());
for (int x : v) {
cout << x << " ";
}
Example
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> marks = {72, 85, 64};
marks.push_back(90);
cout << marks.size() << " " << marks[0] << " " << marks.back() << endl;
marks.pop_back();
int sum = 0;
for (int m : marks) {
sum += m;
}
cout << sum << endl;
return 0;
}Line by line
marksstarts with three elements.push_backadds a fourth, and the vector grows by itself.size,[0]andbackread from it.pop_backremoves the last element, 90.- The loop adds up the three that remain.
Expected result
4 72 90
221
In the real world
vector is the most used container in C++. Because its elements sit next to each other in memory, it is often faster in practice than cleverer structures.
Common mistakes
- Using
v[i]past the end, which is undefined behaviour. - Reading
v.back()of an empty vector. - Comparing an
intwithv.size()when the int can be negative, becausesizeis unsigned. - Changing a vector while looping over it with a range-based for.
Best practices
- Use
vectorinstead of arrays by default. - Pass vectors by
const&when only reading them. - Use a range-based for unless you need the index.
Summary
vector is a list that grows by itself and knows its size. push_back adds, range-based for visits, sort orders, and a vector of vectors makes a table.
Quick check
Key takeaways
- A vector knows its own size and manages its own memory.
- Use a range-based for when you do not need the index.
- Use at() when you want a bad index caught.
Practice problems for this lesson
My notes
Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.