1、前言ios
首先说明,vector能够理解为动态数组,既然是数组,那么它在内存中就应该是一块连续的内存,但vector是如何支持动态增加的呢?关于这个问题,网上有很对说法,但其中有些说法是错误的,最近看到有一篇博友的解释就很是正确vector空间动态增加,这里就针对的他的解释进行进一步的阐述,并进行实际验证。数组
2、vector内存增加方式函数
C++primer中屡次明确指出对vector使用的建议是:先建立一个空的vector对象,而后再运行时再利用vector的成员函数push_back向其中添加元素。先以此来验证vector的内存的自动增加,程序说明为:建立一个空的vector a,而后采用push_back向其中添加元素,共迭代10次,运行环境为VS2010IDE布局
- #include <iostream>
- #include <vector>
- using namespace std;
- int main()
- {
- vector<int> a;
- cout << "a.size(): " << a.size() << " a.capacity(): " << a.capacity() << endl;
- for (int i = 0; i < 10; i++)
- {
- a.push_back(i);
- cout << "a.size(): " << a.size() << " a.capacity(): " << a.capacity() << endl;
- }
- return 0;
- }
运行结果为:spa

在分析结果以前,首先介绍与vector的内存布局,而后再介绍与内存增加相关的四个函数,分别为size()、capacity()、reserve()、resize()函数。.net
(1)vector内存布局对象

start迭代器指向已用空间的首元素,finish指向已用空间的尾元素的下一个位置,end_of_storage指向可用空间的末尾。blog
(2)size()、capacity()、reserve()、resize()函数内存
size()函数返回的是已用空间大小,capacity()返回的是总空间大小,capacity()-size()则是剩余的可用空间大小。当size()和capacity()相等,说明vector目前的空间已被用完,若是再添加新元素,则会引发vector空间的动态增加。reserve(n)预先分配一块较大的指定大小的内存空间,其中n为分配空间大小;resize()成员函数只改变元素的数目,不改变vector的容量。ci
再看刚刚的运行结果,首先能够肯定,在VS2010的编译器里面每次并非增加固定的内存,能够看出是增加当前内存的一半。并且因为咱们的程序没有调用reserve(n)函数预先分配一块内存,因此内存增加是编译器自动完成的。这个自动增加包括从新分配内存空间、拷贝原空间、释放原空间三个过程,具体策略为当添加元素时,若是vector空间大小不足,则会以原大小的1.5倍另外配置一块较大的新空间,而后将原空间内容拷贝过来,在新空间的内容末尾添加元素,并释放原空间。也就是说vector的空间动态增长大小,并非在原空间以后的相邻地址增长新空间,由于vector的空间是线性连续分配的,不能保证原空间以后有可供配置的空间。这就解释了上述程序的运行结果。
可是,针对以上自动完成的内存增加过程,因为包括从新分配内存空间、拷贝原空间、释放原空间等步骤,这些过程会下降程序效率,所以可使用reserve(n)预先分配一块较大的指定大小的内存空间,这样当指定大小的内存空间未使用完时,是不会从新分配内存空间的,这样便提高了效率。下面对上一个程序进行扩展以下,即再定义一个vector b,预先分配10个内存,进行11次push_back操做
- #include <iostream>
- #include <vector>
- using namespace std;
- int main()
- {
- vector<int> a;
- cout << "a.size(): " << a.size() << " a.capacity(): " << a.capacity() << endl;
- for (int i = 0; i < 10; i++)
- {
- a.push_back(i);
- cout << "a.size(): " << a.size() << " a.capacity(): " << a.capacity() << endl;
- }
- cout << endl;
- vector<int> b;
- b.reserve(10);
- for (int i = 0; i < 10; i++)
- {
- b.push_back(i);
- cout << "b.size(): " << b.size() << " b.capacity(): " << b.capacity() << endl;
- }
- b.push_back(11);
- cout << "b.size(): " << b.size() << " b.capacity(): " << b.capacity() << endl;
- cout << endl;
- return 0;
- }
运行结果以下:

能够看到,在调用了reserve(10)进行预先内存分配以后,前10次push_back操做vector b 的capacity并无增加,可是在第11次push_back操做时,因为当前b的size() > capacity(),因此vector自动进行了内存扩充,由10变为15(1.5倍)。也就是说,前10次能避免每次都进行内存扩充,能有效提升效率,可是第11次就不会。但有一点要注意,若是在当前容量没有用完的状况下,再一次调用reserve(n)函数时,只有当n > 当前capacity()时,vector当前容量才会改变。再对上述程序进行扩展,分别加上b.reserve(13)和reserve(20),以下
- #include <iostream>
- #include <vector>
- using namespace std;
- int main()
- {
- vector<int> a;
- cout << "a.size(): " << a.size() << " a.capacity(): " << a.capacity() << endl;
- for (int i = 0; i < 10; i++)
- {
- a.push_back(i);
- cout << "a.size(): " << a.size() << " a.capacity(): " << a.capacity() << endl;
- }
- cout << endl;
- vector<int> b;
- b.reserve(10);
- for (int i = 0; i < 10; i++)
- {
- b.push_back(i);
- cout << "b.size(): " << b.size() << " b.capacity(): " << b.capacity() << endl;
- }
- b.push_back(11);
- cout << "b.size(): " << b.size() << " b.capacity(): " << b.capacity() << endl;
- cout << endl;
-
-
- b.reserve(13);
- cout << "after b.reserve(13):" << endl;
- cout << "b.size(): " << b.size() << " b.capacity(): " << b.capacity() << endl;
-
-
- <span style="white-space:pre;"> </span>b.reserve(20);
- cout << "after b.reserve(20):" << endl;
- cout << "b.size(): " << b.size() << " b.capacity(): " << b.capacity() << endl;
- return 0;
- }
运行结果为:

能够看到,在加上b.reserve(13),容器b的capacity并无由15变为13,但加上 b.reserve(20)时却变化了;这也验证了上述结论。
对于resize()成员函数只改变元素的数目,不改变vector的容量的说法能够从下面的程序进行验证:
- #include <iostream>
- #include <vector>
- using namespace std;
- int main()
- {
- vector<int> a;
- cout << "a.size(): " << a.size() << " a.capacity(): " << a.capacity() << endl;
- for (int i = 0; i < 10; i++)
- {
- a.push_back(i);
- cout << "a.size(): " << a.size() << " a.capacity(): " << a.capacity() << endl;
- }
- cout << endl;
- vector<int> b;
- b.reserve(10);
- for (int i = 0; i < 10; i++)
- {
- b.push_back(i);
- cout << "b.size(): " << b.size() << " b.capacity(): " << b.capacity() << endl;
- }
- b.push_back(11);
- cout << "b.size(): " << b.size() << " b.capacity(): " << b.capacity() << endl;
- cout << endl;
-
- b.reserve(13);
- cout << "after b.reserve(13):" << endl;
- cout << "b.size(): " << b.size() << " b.capacity(): " << b.capacity() << endl;
-
- b.resize(5);
- cout << "after b.resize(5):" << endl;
- cout << "b.size(): " << b.size() << " b.capacity(): " << b.capacity() << endl;
-
- for (int i = 0; i < b.size(); i++)
- {
- cout << b[i] << endl;
- }
- return 0;
- }
运行结果为:

能够看到,在加上resize(5)以后,容器的capacity()并无增加,只是size()变为了5,并且经过打印vector元素可知,只截取了前五个元素。