C++ <vector> reserve function

C++ container class <vector>


reserveis used in vector toPreallocate memoryimportant function that can significantly improve the performance of adding elements.

reserveis a member function of the container class, used toReserve storage space for at least n elementsThis does not change the size of the container, but it pre-allocates enough memory to avoid frequent reallocation when elements are added later.

reserveis a key function for optimizing vector performance, especially suitable for scenarios where a large number of elements need to be added.

Word Definitions: reservemeans "reserve", i.e., pre-reserving enough space.


Basic syntax and parameters

reserveis a member function of the container class, and you need to specify the number of elements to reserve.

Syntax format

void reserve(size_type n);

Parameter description

  • Parameter: n
    • Type:size_type(unsigned integer type, usuallysize_t)
    • Description: The minimum number of elements you wish to reserve. The container will allocate at least enough memory to hold n elements.

Function description

  • Return Value: void(No return value).
  • EffectThe container will reallocate memory so that its capacity is at least n. The container'ssize()will not change, and will remain the original number of elements.
  • NoteIf n is less than the current capacity,reserveit will do nothing. If n is greater than the current capacity, memory will be reallocated.

Example

Let's thoroughly master [it] through a series of examples.reserveUsage.

Example 1: Basic usage - pre-allocating space

Example

#include <iostream>
#include <vector>

int main() {
    // Create an empty vector
    std::vector<int> numbers;

    std::cout << "Initial state - size: " << numbers.size()
              << ", capacity: " << numbers.capacity() << std::endl;

    // Reserve space for 100 elements
    numbers.reserve(100);

    std::cout << "After reserve(100) - size: " << numbers.size()
              << ", capacity: " << numbers.capacity() << std::endl;

    // Add elements
    for(int i = 0; i < 10; ++i) {
        numbers.push_back(i);
    }

    std::cout << "After adding 10 elements - size: " << numbers.size()
              << ", capacity: " << numbers.capacity() << std::endl;

    return 0;
}

Expected output:

初始状态 - size: 0, capacity: 0
reserve(100) 后 - size: 0, capacity: 100
添加 10 个元素后 - size: 10, capacity: 100

Code analysis:

  1. reserve(100)Memory space capable of holding 100 elements was pre-allocated.
  2. size()is still 0, because no elements have been added yet.
  3. After adding 10 elements, the capacity is still 100, and no memory reallocation has occurred.

Example 2: Using reserve to optimize adding large amounts of data

For scenarios where a large number of elements need to be added, using [reserve] in advancereservecan significantly improve performance.

Example

#include <iostream>
#include <vector>
#include <chrono>

int main() {
    const int N = 100000;

    // Without using reserve
    std::vector<int> v1;
    auto start1 = std::chrono::high_resolution_clock::now();
    for(int i = 0; i < N; ++i) {
        v1.push_back(i);
    }
    auto end1 = std::chrono::high_resolution_clock::now();
    auto duration1 = std::chrono::duration_cast<std::chrono::microseconds>(end1 - start1);

    // Using reserve
    std::vector<int> v2;
    v2.reserve(N);
    auto start2 = std::chrono::high_resolution_clock::now();
    for(int i = 0; i < N; ++i) {
        v2.push_back(i);
    }
    auto end2 = std::chrono::high_resolution_clock::now();
    auto duration2 = std::chrono::duration_cast<std::chrono::microseconds>(end2 - start2);

    std::cout << "Time taken without reserve: " << duration1.count() << " microseconds" << std::endl;
    std::cout << "Time taken with reserve: " << duration2.count() << " microseconds" << std::endl;
    std::cout << "Performance improvement: " << (double)duration1.count() / duration2.count() << "x" << std::endl;

    return 0;
}

Code analysis:

  • When adding 100,000 elements, using [reserve] in advancereservecan significantly reduce the number of memory reallocations.
  • This can bring noticeable performance improvements when processing large amounts of data.

Example 3: The correct way to use reserve

To fully utilizereserveyou should estimate the required capacity in advance.

Example

#include <iostream>
#include <vector>

int main() {
    // Assume we want to store data for 1000 users
    struct User {
        std::string name;
        int age;
    };

    std::vector<User> users;
    users.reserve(1000); // pre-allocate space

    // Simulate loading user data
    for(int i = 0; i < 1000; ++i) {
        User u;
        u.name = "User" + std::to_string(i);
        u.age = 20 + (i % 50);
        users.push_back(u);
    }

    std::cout << "Number of users: " << users.size() << std::endl;
    std::cout << "Capacity: " << users.capacity() << std::endl;

    return 0;
}

Code analysis:

  • For loading data of a known size, using [reserve] in advancereserveis the best practice.
  • This avoids multiple memory reallocations and improves efficiency.

Example 4: Avoiding unnecessary reserve

reserveIt should be used according to actual needs; over-allocating will waste memory.

Example

#include <iostream>
<vector>

int main() {
    // Wrong approach: over-preallocation
    std::vector<int> v1;
    v1.reserve(1000000); // Only 10 elements are needed, but we preallocated space for 1 million!

    for(int i = 0; i < 10; ++i) {
        v1.push_back(i);
    }

    std::cout << "Only 10 elements needed - size: " << v1.size()
              << ", capacity: " << v1.capacity() << std::endl;

    // Correct approach: preallocate as needed
    std::vector<int> v2;
    v2.reserve(10);

    for(int i = 0; i < 10; ++i) {
        v2.push_back(i);
    }

    std::cout << Need 10 elements - size: << v2.size()
              << ", capacity: " << v2.capacity() << std::endl;

    return 0;
}

Code analysis:

  • Excessive preallocation wastes memory space.
  • should be set based on the actual number of elements needed.reserveof the parameter.

Example 5: reserve and capacity checking

You can check whether the capacity is sufficient before adding elements.

Example

#include <iostream>
#include <vector>

void addElements(std::vector<int>& v, int count) {
    // If the current capacity is insufficient, reserve enough space
    if(v.capacity() < v.size() + count) {
        v.reserve(v.size() + count);
    }

    // Add elements
    for(int i = 0; i < count; ++i) {
        v.push_back(v.size());
    }
}

int main() {
    std::vector<int> data;

    std::cout << "initial - size: " << data.size()
              << ", capacity: " << data.capacity() << std::endl;

    addElements(data, 50);
    std::cout << After adding 50 - size: << data.size()
              << ", capacity: " << data.capacity() << std::endl;

    addElements(data, 50);
    std::cout << After adding another 50 - size: << data.size()
              << ", capacity: " << data.capacity() << std::endl;

    return 0;
}

Code analysis:

  • You can dynamically check and reserve capacity within a function.
  • This ensures that no memory reallocation occurs when adding elements.

C++ container class <vector>

other extensions