Skip to content
C++ Basics: Refresh Iterators After Reserving an Unordered Map

C++ Basics: Refresh Iterators After Reserving an Unordered Map

November 3, 2026

Separate iterator invalidation from element reference stability when reserving hash-table capacity.

Prepare a scratch directory

Tested on Linux x86_64 with GCC 14.2.0. Install a C++20-capable compiler and its standard-library headers, with g++ on PATH. You also need Bash, a text editor, and the mktemp, rm, and rmdir utilities. No third-party library is required.

Keep the same terminal open. Stop if setup fails, before saving the source:

start_directory="$PWD"
work_directory="$(mktemp -d)" || exit 1
cd -- "$work_directory" || exit 1

Run the example

Save this as unordered-map-rehash-handles-demo.cpp:

#include <iostream>
#include <string>
#include <unordered_map>

int main() {
    std::unordered_map<std::string, int> counters{{"requests", 7}};
    int& request_count = counters.at("requests");
    counters.reserve(100);
    ++request_count;
    const auto current = counters.find("requests");
    std::cout << "Retained reference: " << request_count << '\n';
    std::cout << "Fresh iterator: " << current->second << '\n';
    std::cout << "Entries: " << counters.size() << '\n';
}

Compile and run it. The second command runs only after compilation succeeds:

g++ -std=c++20 -Wall -Wextra -Werror -pedantic unordered-map-rehash-handles-demo.cpp -o unordered-map-rehash-handles-demo &&
./unordered-map-rehash-handles-demo

Observed output:

Retained reference: 8
Fresh iterator: 8
Entries: 1

Read the result

The reference still identifies the same mapped value after reserve. The example obtains its iterator afterward, so it never dereferences a stale iterator.

Apply it carefully

Rehashing invalidates iterators but not references or pointers to retained elements. Treat reserve as an iterator boundary and reacquire iterators. Erasing an element still invalidates its references. Reserve plans buckets for a requested element count; it neither inserts elements nor promises an exact bucket count. Future growth can rehash again.

The C++ working draft documents the relevant container rules. This example uses only features available in C++20, even though the linked draft also includes newer additions.

Clean up

Remove only the source and executable created here, then remove the empty practice directory:

rm -- unordered-map-rehash-handles-demo.cpp unordered-map-rehash-handles-demo
cd -- "$start_directory" || exit 1
rmdir -- "$work_directory"
unset start_directory work_directory

If the directory is not empty, inspect its remaining contents before removing anything else.

Acknowledgements

This post was created with assistance from AI.

Last updated on