vector内存增长方式

一、前言

    首先说明,vector可以理解为动态数组,既然是数组,那么它在内存中就应该是一块连续的内存,但vector是如何支持动态增长的呢?关于这个问题,网上有很对说法,但其中有些说法是错误的,最近看到有一篇博友的解释就非常正确vector空间动态增长,这里就针对的他的解释进行进一步的阐述,并进行实际验证。

二、vector内存增长方式

   C++primer中多次明确指出对vector使用的建议是:先创建一个空的vector对象,然后再运行时再利用vector的成员函数push_back向其中添加元素。先以此来验证vector的内存的自动增长,程序说明为:创建一个空的vector a,然后采用push_back向其中添加元素,共迭代10次,运行环境为VS2010IDE

 
  1. #include <iostream>

  2. #include <vector>

  3. using namespace std;

  4. int main()

  5. {

  6. vector<int> a;

  7. cout << "a.size(): " << a.size() << " a.capacity(): " << a.capacity() << endl;

  8. for (int i = 0; i < 10; i++)

  9. {

  10. a.push_back(i);

  11. cout << "a.size(): " << a.size() << " a.capacity(): " << a.capacity() << endl;

  12. }

  13. return 0;

  14. }

运行结果为:

    在分析结果之前,首先介绍与vector的内存布局,然后再介绍与内存增长相关的四个函数,分别为size()、capacity()、reserve()、resize()函数。

(1)vector内存布局

    start迭代器指向已用空间的首元素,finish指向已用空间的尾元素的下一个位置,end_of_storage指向可用空间的末尾。

(2)size()、capacity()、reserve()、resize()函数

 

    size()函数返回的是已用空间大小,capacity()返回的是总空间大小,capacity()-size()则是剩余的可用空间大小。当size()和capacity()相等,说明vector目前的空间已被用完,如果再添加新元素,则会引起vector空间的动态增长。reserve(n)预先分配一块较大的指定大小的内存空间,其中n为分配空间大小;resize()成员函数只改变元素的数目,不改变vector的容量。

    再看刚刚的运行结果,首先可以确定,在VS2010的编译器里面每次并不是增长固定的内存,可以看出是增长当前内存的一半。而且由于我们的程序没有调用reserve(n)函数预先分配一块内存,所以内存增长是编译器自动完成的。这个自动增长包括重新分配内存空间、拷贝原空间、释放原空间三个过程,具体策略为当添加元素时,如果vector空间大小不足,则会以原大小的1.5倍另外配置一块较大的新空间,然后将原空间内容拷贝过来,在新空间的内容末尾添加元素,并释放原空间。也就是说vector的空间动态增加大小,并不是在原空间之后的相邻地址增加新空间,因为vector的空间是线性连续分配的,不能保证原空间之后有可供配置的空间。这就解释了上述程序的运行结果。

    但是,针对以上自动完成的内存增长过程,由于包括重新分配内存空间、拷贝原空间、释放原空间等步骤,这些过程会降低程序效率,因此可以使用reserve(n)预先分配一块较大的指定大小的内存空间,这样当指定大小的内存空间未使用完时,是不会重新分配内存空间的,这样便提升了效率。下面对上一个程序进行扩展如下,即再定义一个vector b,预先分配10个内存,进行11次push_back操作

 
  1. #include <iostream>

  2. #include <vector>

  3. using namespace std;

  4. int main()

  5. {

  6. vector<int> a;

  7. cout << "a.size(): " << a.size() << " a.capacity(): " << a.capacity() << endl;

  8. for (int i = 0; i < 10; i++)

  9. {

  10. a.push_back(i);

  11. cout << "a.size(): " << a.size() << " a.capacity(): " << a.capacity() << endl;

  12. }

  13. cout << endl;

  14. vector<int> b;

  15. b.reserve(10);

  16. for (int i = 0; i < 10; i++)

  17. {

  18. b.push_back(i);

  19. cout << "b.size(): " << b.size() << " b.capacity(): " << b.capacity() << endl;

  20. }

  21. b.push_back(11);

  22. cout << "b.size(): " << b.size() << " b.capacity(): " << b.capacity() << endl;

  23. cout << endl;

  24. return 0;

  25. }

运行结果如下:


    可以看到,在调用了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),如下

 
  1. #include <iostream>

  2. #include <vector>

  3. using namespace std;

  4. int main()

  5. {

  6.     vector<int> a;

  7.     cout << "a.size(): " << a.size() << "   a.capacity(): " << a.capacity() << endl;

  8.     for (int i = 0; i < 10; i++)

  9.     {

  10.         a.push_back(i);

  11.         cout << "a.size(): " << a.size() << "   a.capacity(): " << a.capacity() << endl;

  12.     }

  13.     cout << endl;

  14.     vector<int> b;

  15.     b.reserve(10);

  16.     for (int i = 0; i < 10; i++)

  17.     {

  18.         b.push_back(i);

  19.         cout << "b.size(): " << b.size() << "   b.capacity(): " << b.capacity() << endl;

  20.     }

  21.     b.push_back(11);

  22.     cout << "b.size(): " << b.size() << "       b.capacity(): " << b.capacity() << endl;

  23.     cout << endl;

  24.  
  25.  
  26.     b.reserve(13);

  27.     cout << "after b.reserve(13):" << endl;

  28.     cout << "b.size(): " << b.size() << "       b.capacity(): " << b.capacity() << endl;

  29.  
  30.  
  31. b.reserve(20);

  32.     cout << "after b.reserve(20):" << endl;

  33.     cout << "b.size(): " << b.size() << "       b.capacity(): " << b.capacity() << endl;

  34.     return 0;

  35. }

运行结果为:

 可以看到,在加上b.reserve(13),容器b的capacity并没有由15变为13,但加上 b.reserve(20)时却变化了;这也验证了上述结论。

   对于resize()成员函数只改变元素的数目,不改变vector的容量的说法可以从下面的程序进行验证:

 
  1. #include <iostream>

  2. #include <vector>

  3. using namespace std;

  4. int main()

  5. {

  6. vector<int> a;

  7. cout << "a.size(): " << a.size() << " a.capacity(): " << a.capacity() << endl;

  8. for (int i = 0; i < 10; i++)

  9. {

  10. a.push_back(i);

  11. cout << "a.size(): " << a.size() << " a.capacity(): " << a.capacity() << endl;

  12. }

  13. cout << endl;

  14. vector<int> b;

  15. b.reserve(10);

  16. for (int i = 0; i < 10; i++)

  17. {

  18. b.push_back(i);

  19. cout << "b.size(): " << b.size() << " b.capacity(): " << b.capacity() << endl;

  20. }

  21. b.push_back(11);

  22. cout << "b.size(): " << b.size() << " b.capacity(): " << b.capacity() << endl;

  23. cout << endl;

  24.  
  25. b.reserve(13);

  26. cout << "after b.reserve(13):" << endl;

  27. cout << "b.size(): " << b.size() << " b.capacity(): " << b.capacity() << endl;

  28.  
  29. b.resize(5);

  30. cout << "after b.resize(5):" << endl;

  31. cout << "b.size(): " << b.size() << " b.capacity(): " << b.capacity() << endl;

  32.  
  33. for (int i = 0; i < b.size(); i++)

  34. {

  35. cout << b[i] << endl;

  36. }

  37. return 0;

  38. }

运行结果为:

可以看到,在加上resize(5)之后,容器的capacity()并没有增长,只是size()变为了5,而且通过打印vector元素可知,只截取了前五个元素。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值