Skip to content

38 Intermediate The Hundred

reserve Is Not resize

the score you wrote down, and then couldn't find

#include <iostream>
#include <vector>

int main() {
    std::vector<int> scores;
    scores.reserve(5);   // make room for five scores
    std::cout << "size " << scores.size() << ", capacity " << scores.capacity() << "\n";

    scores[0] = 42;   // record the first score
    std::cout << "stored " << scores[0] << ", size " << scores.size() << "\n";

    scores.push_back(7);   // and now the second one
    std::cout << "scores[0] is " << scores[0] << ", size " << scores.size() << "\n";
}

Run it. Where does 42 end up?

Answer

Nowhere. Typical output (GCC on x86-64), identical at -O0 through -O3:

size 0, capacity 5
stored 42, size 0
scores[0] is 7, size 1

The vector hands back 42 while still reporting a size of 0 — and then loses it.

Why

reserve(5) buys space, not elements: it allocates a buffer for five ints and leaves size() at 0. So scores[0] indexes past the last element — there is no element zero — and the write is undefined behavior. It appears to work because the storage really is there and nobody else is using it yet, so the read hands back your 42. Then push_back(7) constructs at index size(), still 0, and stamps 7 right on top — the vector never knew about your value. scores.at(0) would have thrown: the checked accessor asks about size.

Nothing warns by default — not -Wall -Wextra, nor stock -fsanitize=address on libstdc++. -D_GLIBCXX_ASSERTIONS aborts (Assertion '__n < this->size()' failed), and ASan does flag it as a container-overflow once vector annotations are on (-D_GLIBCXX_SANITIZE_VECTOR).

The fix

Use resize when you want elements, reserve when you only want to avoid reallocation:

scores.resize(5);   // five real elements, value-initialized to 0
scores[0] = 42;     // legal — element 0 exists

std::vector<int> other;
other.reserve(5);      // still empty: you must grow it, you may not index it
other.push_back(42);   // one of five that fit without reallocating

Takeaway: capacity is room, size is elements — indexing is only valid below size().

Try it: g++ -std=c++17 main.cpp -o demo && ./demo

Open in Compiler Explorer ↗ Quiz this entry