操作大小的函数

        在Vector容器中有以下几个关于大小的函数
方法效果
size()返回容器的大小
empty()判断容器是否为空
max_size()返回容器最大的可以存储的元素
capacity()返回容器当前能够容纳的元素数量

例子一:

      该例子主要展示了关于大小操作函数的使用与区别
[cpp]  view plain  copy
  1. int _tmain(int argc, _TCHAR* argv[])  
  2. {  
  3.     vector<string> sentence;  
  4.     sentence.reserve(5);  
  5.       
  6.     //append some elements  
  7.     sentence.push_back("hello");  
  8.     sentence.push_back("how");  
  9.     sentence.push_back("are");  
  10.     sentence.push_back("you");  
  11.     sentence.push_back("?");  
  12.     copy(sentence.begin(), sentence.end(), ostream_iterator<string>(cout, " "));  
  13.     cout << endl;  
  14.   
  15.     //print "technical data"  
  16.     cout << "max_size():" << sentence.max_size() << endl;  
  17.     cout << "size():" << sentence.size() << endl;  
  18.     cout << "capacity():" << sentence.capacity() << endl;  
  19.       
  20.     cout << "**************************" << endl;  
  21.       
  22.     //swap second and fourth element  
  23.     swap(sentence[1], sentence[3]);   
  24.     //insert element "always" before element "?"  
  25.     sentence.insert(find(sentence.begin(), sentence.end(), "?"), "always");  
  26.     //assign "!" to the last element  
  27.     sentence.back() = "!";  
  28.     copy(sentence.begin(), sentence.end(), ostream_iterator<string>(cout, " "));  
  29.     cout << endl;  
  30.   
  31.     //print "technical data"  
  32.     // return maximum possible length of sequence   
  33.     //回容器的最大可以存储的元素个数,这是个极限,当容器扩展到这个最大值时就不能再自动增大  
  34.     cout << "max_size():" << sentence.max_size() << endl;  
  35.     // return length of sequence  
  36.     cout << "size():" << sentence.size() << endl;  
  37.     // return current length of allocated storage  
  38.     cout << "capacity():" << sentence.capacity() << endl;  
  39.     return 0;  
  40. }  
        Vector的容量之所以重要,有以下两个原因:
         1. 容器的大小一旦超过capacity的大小,vector会重新配置内部的存储器,导致和vector元素相关的所有reference、pointers、iterator都会失效。
         2.内存的重新配置会很耗时间。
例子二:
该例子主要介绍了容器的重新配置导致iterator失效问题。
[cpp]  view plain  copy
  1. int _tmain(int argc, _TCHAR* argv[])  
  2. {  
  3.     vector<string> strVector;  
  4.     strVector.reserve(5);//当前空间够大,不会发生重新配置,插入新元素后有可能会重新分配  
  5.   
  6.     strVector.push_back("hello");  
  7.     strVector.push_back("C++");  
  8.     strVector.push_back("world");  
  9.   
  10.     vector<string>::iterator it = strVector.begin();  
  11.     cout << "chang size befor, the first elemt:" << *it << endl;  
  12.   
  13.     cout << "push_back one elems:." << endl;  
  14.     strVector.push_back("MS");  
  15.     cout << "push_back one elemt after, the first elemt:" << *it << endl;  
  16.   
  17.     cout << "push_back two elems:" << endl;  
  18.     strVector.push_back("HW");  
  19.     strVector.push_back("BAT");//当前大小超过当前的容量,导致重新分配内存  
  20.     //it = strVector.begin(); 内存重新分配后,重新获取指针可以避免指针失效  
  21.     cout << "push_back two elemts after, the first elemt:"<< *it << endl;//指针失效导致程序奔溃,  
  22.   
  23.     return 0;  
  24. }  

避免内存重新配置的方法

方法一:Reserve()保留适当容量

       在创建容器后,第一时间为容器分配足够大的空间,避免重新分配内存。
[cpp]  view plain  copy
  1. std::vector<int> v;//create an empty vector  
  2. v.reverse(80);// reserve memory for 80 elements  

方法二:利用构造函数创建出足够空间

      该方法是创建容器时,利用构造函数初始化的出足够的空间,       
[cpp]  view plain  copy
  1. std::vector<int> v(80);  

Vector内存扩展方式

           vector内存成长方式可归结以下三步曲:
(1)另觅更大空间;
(2)将原数据复制过去;
(3)释放原空间三部曲。
如果不是vector每次配置新空间时都有留下一些余裕,其成长假象所带来的代价将是相当高昂,从内存的扩展方式就可以看出向vector插入元素,可能导致迭代器失效的原理。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐