std::vector::reserve

std::vector::reserve 函数在 C++ 中用于预分配内存,避免在元素增加时多次重新分配内存,从而提高性能。

它最常用于需要频繁向 vector 中添加元素,并且可以预估容器的最终大小的场景。

作用

reserve 函数的主要作用是:

  1. 预分配容量:它提前为 vector 分配一定数量的内存(但不会改变当前 vector 的元素数量 size)。也就是说,它只是增加 vector 的容量 capacity,使其能够容纳更多元素,而不需要反复分配和释放内存。

  2. 避免多次内存分配和拷贝:在 vector 中,如果你频繁调用 push_back 向容器添加新元素,而没有事先为 vector 分配足够的容量,容器在容量不足时会自动扩容。这会导致每次扩容时进行内存分配,并将现有元素拷贝到新的内存地址。reserve 通过提前分配足够的空间,减少或避免了这些昂贵的操作。

场景

reserve 通常用于以下场景:

  1. 已知或可以预估元素的数量:如果你知道或者可以大致估计 vector 最终会存储多少个元素,可以使用 reserve 来一次性分配足够的内存空间,避免扩容时频繁的内存分配与拷贝。

    示例:

    #include <iostream>
    #include <vector>
    
    int main() {
        std::vector<int> vec;
        vec.reserve(100);  // 预先分配100个元素的空间
    
        for (int i = 0; i < 100; ++i) {
            vec.push_back(i);  // 不会触发多次扩容
        }
    
        std::cout << "Vector size: " << vec.size() << std::endl;
        std::cout << "Vector capacity: " << vec.capacity() << std::endl;
    
        return 0;
    }
    

    在这个例子中,调用 reserve(100) 会一次性分配能够容纳 100 个元素的内存空间。因此,在 push_back 添加元素时,不会频繁地重新分配内存,提升了性能。

  2. 性能优化在高性能的应用中,特别是需要处理大量数据时,如果向 vector 中添加元素的操作非常频繁且每次添加元素都会导致 vector 扩容,会严重影响性能。reserve 可以通过减少内存分配和拷贝操作来提升性能。

  3. 避免扩容导致的迭代器失效vector 扩容时,之前的元素会被拷贝到新的内存地址,导致之前的迭代器失效。如果提前使用 reserve 分配好足够的空间,可以避免这种问题,特别是在对迭代器的连续访问中。

    迭代器失效示例:

    #include <iostream>
    #include <vector>
    
    int main() {
        std::vector<int> vec;
        vec.reserve(10);  // 预留空间避免迭代器失效
    
        vec.push_back(1);
        vec.push_back(2);
        vec.push_back(3);
    
        // 获取迭代器
        auto it = vec.begin();
    
        // 继续向vector添加元素
        vec.push_back(4);  // 不会导致迭代器失效
    
        std::cout << "First element: " << *it << std::endl;  // 输出正确结果
        
        return 0;
    }
    

reserveresize 的区别

  • reserve:只改变 vector容量,但不改变其大小。也就是说,它只预分配内存,但并不实际增加或减少 vector 中的元素。
  • resize:不仅改变 vector大小,还会相应地创建或销毁元素。它会让 vector 的大小变为指定的大小,添加默认构造的元素(如果扩大),或删除多余的元素(如果缩小)。

示例:

std::vector<int> vec;
vec.reserve(10);  // 仅分配内存,但不添加元素,vec.size() 仍为 0

vec.resize(10);  // 改变size,vec.size() 为 10,默认值填充

总结

std::vector::reserve 在以下场景非常有用:

  • 需要大量动态添加元素时。
  • 知道或能够预估元素的数量时。
  • 想要避免不必要的内存分配、拷贝和迭代器失效时。

通过合理使用 reserve,可以有效地优化程序的性能,减少 vector 的内存管理开销。

posted @ 2024-09-25 20:40  牛马chen  阅读(353)  评论(0编辑  收藏  举报