./Ilia Munaev – Software Engineer

reserve() in C++. Trade-off between Speed and Memory Utilization

Overview

std::string::reserve() pre-allocates capacity for a string. If we know the final size of the result, reserving that capacity up front avoids repeated reallocations and copying during concatenation.

This is mainly a memory-allocation efficiency technique. It can also improve runtime, but this write-up focuses on memory behavior.

Task

  1. Given (for example):
    const std::vector<std::string>& words = {"hello", "42"};
    
  2. Task: Concatenate all elements of words into a single string and return it.

  3. Expected result:
    std::string result = concatWords(words);
    result == "hello42";  // true
    
  4. Constraints:
    • Memory usage efficiency is the priority
    • Runtime performance is not the primary concern

Solution: 2 Options

Option 1: Allocation-naive

std::string concatWords(const std::vector<std::string>& words) {
    std::string s;
    for (const auto& w : words)
        s.append(w);

    return s;
}
  1. The string grows dynamically

  2. May reallocate memory multiple times

Option 2: Memory-efficient

std::string concatWords(const std::vector<std::string>& words) {
    size_t total = 0;
    for (const auto& w : words)
        total += w.size();

    std::string s;
    s.reserve(total);

    for (const auto& w : words)
        s.append(w);

    return s;
}
  1. Exactly one allocation
  2. No buffer growth
  3. No copying of previously written data

In Option1 std::string::append() will reallocate memory when the current buffer capacity is smaller than the required size of the new string.

In Option 2 calling reserve(total) guarantees that the string’s internal buffer has at least total bytes of capacity, so no memory reallocation will occur while appending up to that size.

Conclusion

  1. std::string::reserve() allows to control memory growth and prevent repeated reallocations during concatenation.
  2. When the final size is known, reserving capacity up front produces the same result with fewer allocations and less memory movement, making it the correct approach when memory efficiency matters.