C++面试题(6)| vector扩容过程你理解了吗?

782 阅读2分钟

本文已参与[新人创作礼]活动,一起开启掘金创作之路。

image.png

(欢迎大家关注我的微信公众号——控制工程研习,上面会分享很多我学习过程中总结的笔记。)

1. vector的扩容过程?

    (1)分配一块大小是当前 vector 容量几倍的新存储空间。注意,多数 STL 版本中的 vector 容器,其容器都会以 2 的倍数增长,也就是说,每次 vector 容器扩容,它们的容量都会提高到之前的 2 倍;

    (2)将 vector容器存储的所有元素,依照原有次序从旧的存储空间复制到新的存储空间中;

    (3)析构掉旧存储空间中存储的所有元素;

    (4)释放旧的存储空间。

2. vector size和capacity的区别?

    size代表已经用了的元素的大小,capacity表示总共元素的大小;

图片

    比较程序:


#include<iostream>
#include<vector>
using namespace std;
int main()
{
    vector<int> vec;
    cout << vec.capacity() << endl;
    for (int i = 0; i < 10; ++i)
    {
        vec.push_back(i);
        cout << "size: " << vec.size() << endl;
        cout << "capacity: " << vec.capacity() << endl;
    }
    system("pause");
    return 0;
}

结果在VS2019上运行:

图片

3. 有什么方法能够避免vector的动态扩容过程呢?

避免动态扩容的原因:

    vector容器的扩容过程是非常耗时的,并且当容器进行扩容后,之前和该容器相关的所有指针、迭代器(iterator)以及引用都会失效。因此在使用 vector 容器过程中,我们应尽量避免执行不必要的扩容操作。

方法:

   只要有新元素要添加到 vector 容器中而恰好此时 vector 容器的容量不足时,该容器就会自动扩容。因此,避免 vector 容器执行不必要的扩容操作的关键在于,在使用 vector 容器初期,就要将其容量设为足够大的值。 换句话说,在vector 容器刚刚构造出来的那一刻,就应该借助 reserve() 成员方法为其扩充足够大的容量。

reserve()属性的作用:

    强制 vector 容器的容量至少为 n。注意,如果 n 比当前 vector 容器的容量小,则该方法什么也不会做;反之如果 n 比当前 vector 容器的容量大,则 vector 容器就会扩容。所以,reserve的作用是更改vector的容量(capacity),使vector至少可以容纳n个元素。

    之前的例子加上reserve(5),查看效果:

#include<iostream>
#include<vector>
using namespace std;
int main()
{
    vector<int> vec;
    vec.reserve(5);
    cout << vec.capacity() << endl;
    for (int i = 0; i < 10; ++i)
    {
        vec.push_back(i);
        cout << "size: " << vec.size() << endl;
        cout << "capacity: " << vec.capacity() << endl;
    }
    system("pause");
    return 0;
}

图片

    可以看到capacity在一开始size小于5的情况下一直是5,当超过5时才扩大。

    所以我们在设计时,如果想避免vector动态扩容的过程带来的不良影响(iterator失效等),可以提前考虑和预估这个vector的大致容量,在一开始就设置好。