c++ vector 构造及常用方法 size与capacity()的区别及控制

mac2022-06-30  232

#include <stdio.h> #include <iostream> #include <string> #include <vector> using namespace std; //c++ vector 构造及常用方法 int main() { // 构造 vector<int> v1 = {0,1,2,3,4,5,6,7}; int a[10] = {0,1,2,3}; //默认填充 0 vector<int> v2(10); // == v2[10]; 默认填充 0 vector<int> v3(10,1); // == v2[10]; 填充1 vector<int> v4(v1); vector<int> v5 = v1; vector<int> v6(v1.begin(), v1.end()); //都是左闭右开区间 【) vector<int> v7(a,a+3); //都是左闭右开区间 【) // 空间 // length(string专属) // size capacity empty max_size resize reserve 同 string // 关于capcity() 与 size() 已分配空间大小(大)与实际占用空间大小(小) cout << v1.capacity() << endl; //8 v1.resize(100); cout << v1.capacity() << endl; //100 用0填充 v1.shrink_to_fit(); //收缩空间到合适 令capcity的值 = size cout << v1.capacity() << endl; //100 vector<int>v11 = {0,1,2,3,4,5,6,7}; cout << v11.capacity() << endl; //8 v11.reserve(100); cout << v11.capacity() << endl; //100 v11.shrink_to_fit(); //收缩空间到合适 cout << v11.capacity() << endl; //8 // 取值 cout << v1.front() << endl; cout << v1.back() << endl; cout << v1.at(3) << endl; // 增加 v1.push_back(333); v1.pop_back(); v1.assign(v2.begin()+3,v2.end()-2); //赋值 v1.clear(); v1.swap(v2); // 插入 v1 = {0,1,2,3,4,5,6,7}; v2 = {8,8,8,8,8,8,8,8}; v1.insert(v1.begin()+5, v2.begin()+2, v2.end()-2); //插入都是在标记之前插入 和begin() end()对应 可以插入任何一个位置 for(auto tmp = v1.cbegin(); tmp != v1.cend(); tmp++) //遍历时尽量用 cbegin 避免改变 vector内的值 cout << *tmp << ","; cout << endl; //vector 没有string 中的 find(), replace() // 关于 emplace_back 与 push_back // emplace 与 assign 见另一篇 return 0; }

关于vector空间的分配 c++STL源码:

if (_Count == 0)//这里进行了判断,但是什么都不做,不知道为什么??????? ; else if (max_size() - size() < _Count)//编译器可以申请的最大容量也装不下,抛出异常_THROW(length_error, "vector<T> too long"); _Xlen(); // result too long else if (_Capacity < size() + _Count)//当前空间不足,需要扩容 { // not enough room, reallocate _Capacity = max_size() - _Capacity / 2 < _Capacity ? 0 : _Capacity + _Capacity / 2; // try to grow by 50%,扩容50% if (_Capacity < size() + _Count)//扩容50%后依然不够容下,则使容量等于当前数据个数加上新增数据个数 _Capacity = size() + _Count; pointer _Newvec = this->_Alval.allocate(_Capacity);//申请新的空间 pointer _Ptr = _Newvec; _TRY_BEGIN _Ptr = _Umove(_Myfirst, _VEC_ITER_BASE(_Where), _Newvec); // copy prefix <span style="white-space:pre"> </span>//拷贝原有数据到新的内存中 _Ptr = _Ucopy(_First, _Last, _Ptr); // add new stuff<span style="white-space:pre"> </span>//拷贝新增数据到新的内存的后面 _Umove(_VEC_ITER_BASE(_Where), _Mylast, _Ptr); // copy suffix _CATCH_ALL _Destroy(_Newvec, _Ptr); this->_Alval.deallocate(_Newvec, _Capacity);//释放原来申请的内存

不够时,每次扩容50%。 删除时,缓冲区大小并不会改变,仅仅只是清除了其中的数据。 只有在析构函数调用的时候vector才会自动释放缓冲区。

关于释放空间的方法: 方法1:shrink_to_fit(); 方法2:vector(myvector).swap(myvector); swap居然也可以,不相信的我试了一下

#include <iostream> #include <vector> using namespace std; int main() { vector<int> v1 = {1,2,3,4,5}; v1.reserve(100); cout << v1.size() << endl; cout << v1.capacity() << endl; vector<int>(v1).swap(v1); cout << v1.size() << endl; cout << v1.capacity() << endl; return 0; } 5 100 5 5

居然真的可以。!!!! 然后查了一下为什么: swap()过程:先创建一个临时拷贝与原先的vector一致,此时的拷贝其容量是尽可能小的符合所需数据的。紧接着将该拷贝与原先的vector v进行 交换。执行交换后,临时变量会被销毁,内存得到释放。此时的v即为原先 的临时拷贝,而交换后的临时拷贝则为容量非常大的vector(不过已经被销毁)。


最新回复(0)