【C++】中vector的size和capacity函数、resize和reserve函数介绍和使用

在C++中,理解capacity和size之间的区别非常重要。容器的size是指它已经保存的元素的数目;而capacity则是在不分配新的内存空间的前提下它最多可以保存多少元素。

 当创建空容器时, 容量(capacity)为 0;当用完时,增加原容量的 1/2。 

适用如 vector这种 元素连续存储的容器, 如为list则不同。 
capacity 一般大于size的原因是为了避免每次增加数据时都要重新分配内存,所以一般会生成一个较大的空间,以便随后的数据插入。
2、举例说明 

  1. vector v; //此时没有初始化,所以size()和capacity()都是0;
  2. cout<<v.size()<<endl<<v.capacity()<<endl;
  3. v.push_back(1);
  4. cout<<v.size()<<endl<<v.capacity()<<endl;//此时容器内有一个元素了,那么size()和capacity()都是1
  5. v.push_back(1);
  6. cout<<v.size()<<endl<<v.capacity()<<endl;//此时容器内能够提供的空间capacity()不够用了,需要申请内容,申请多少呢,申请后的大小应该是以前的2倍,那就应该是2了,此时有两个元素,size()为2,capacity()也是2
  7. v.push_back(1);
  8. cout<<v.size()<<endl<<v.capacity()<<endl;//此时容器能够提供的空间是2,又增加元素,不够,需要申请空间,申请后的空间为原来2倍,就是4了,那么size()为3,capacity()为4
  9. v.push_back(1);
  10. cout<<v.size()<<endl<<v.capacity()<<endl;//容器还能够提供一个空间,不需要申请新空间,size()为4,capacity()为4
  11. v.push_back(1);
  12. cout<<v.size()<<endl<<v.capacity()<<endl;//空间不够,需要申请,size()为5,capacity为8
     

    3、capacity()和max_size()比较 
    capacity : 容器的成员函数capacity()取得 
    max_size:容器的成员函数max_size()取得 
    STL容器的capacity属性,表示STL在发生realloc前能允许的最大元素数,也可以理解为预分配的内存空间。例如一个vector v的capacity为5,当插入第6个元素时,vector会realloc,vector内部数据会复制到另外一个内存区域。这样之前指向vector中的元素的指针、迭代器等等均会失效。 
    max_size属性和capacity不同,表示STL容器允许的最大元素数,通常,这个数是一个很大的常整数,可以理解为无穷大。这个数目与平台和实现相关,在我的机器上vector的max_size为1073741823,而string的max_size为4294967294。因为max_size很大~所以基本不会发生元素数超过max_size的情况,只需知道两者区别即可。

    4、一些容器与capacity 
    (1)并不是所有的容器都会发生realloc。 
    List,Map/Multimap,Set/Multiset的元素在内存中散布,不预分配内存,所以不会产生realloc的情况,对于这些容器,其capacity是无意义的,所以这些容器没有capacity()成员函数,也没有capacity属性。 
    (2)deque双向队列情况比较特殊,deque将内存分块,每次分配固定大小的分块,一个分块填充满后开辟新的分块,也属于散布-连续混杂的情况,虽然deque会预分配内存空间,但也不会产生realloc(人家是alloc),所以也不具有capacity属性。 
    (3)实际具有capacity属性的容器只有vector和string,在不同实现下,capacity也不尽相同。 
    除了通过构造式设定capacity,也可以使用reserve(n)来设定容器对象的capacity,避免之后的realloc。不过这一过程是只增不减的,如果n小于当前capacity,则reserve(n)无效。

    vector空间增长问题

     

    (1)size 获取数据个数

      size()函数用于返回容器中元素的个数。

    (2)capacity 获取容量大小

      vector容器的capacity()函数用于返回当前容器的容量,即底层数组能够容纳的最大元素数量。

     size()和capacity()有不同的地方:

      size()函数用于返回容器中当前存储的元素数量,即容器中的实际元素个数。

      capacity()函数用于返回容器底层实际分配的存储空间大小,即容器能够容纳的最大元素数量。
      

    (3)empty 判断是否为空
      empty()函数用于检查vector容器是否为空,即是否没有任何元素。它返回一个布尔值,true表示容器为空,false表示容器非空。

    (4)resize 改变vector的size

      resize()函数用于更改vector容器的大小,以容纳指定数量的元素。 当新的大小大于当前大小时,额外的元素将被默认构造或复制构造。当新的大小小于当前大小时,超出新大小的元素将会被删除。

    (5)reserve 改变vector的capacity
      reserve()函数用于为容器预留一定的存储空间,以便在之后添加元素时减少重新分配内存的次数。 它接受一个参数,即预留空间的大小。注意,预留的空间大小并不会直接改变vector的size。

      使用reserve()函数的目的是优化性能,当我们预知容器可能需要存储大量元素时,可以使用reserve()函数提前分配足够的内存空间,避免频繁的内存重新分配和数据复制。
     

    注意:
      capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的。 这个问题经常会考察,不要固化的认为,vector增容都是2倍,具体增长多少是根据具体的需求定义的。vs是PJ版本STL,g++是SGI版本STL。

    总结:

      resize在开空间的同时还会进行初始化,影响size。

      reserve只负责开辟空间,如果确定知道需要用多少空间,reserve可以缓解vector增容的代价缺陷问题。
     

posted @ 2024-01-26 15:26  konglingbin  阅读(496)  评论(0编辑  收藏  举报