vector:resize和reserve的区别
写在前面
为了区别这两个函数的功能,首先我们需要区别两个属性的概念。
- capacity:发生 realloc 前能允许的最大元素数,即预分配的内存空间。预留位置不初始化,元素不可访问。
- size:当前 vector 容器真实占用的大小,也就是容器当前拥有多少个元素。可以进行遍历。
- capacity >= size。
ps:假设有一瓶容量为500ml的矿泉水,但是现在里面只装了300ml的水,那么capacity即为500,size即为300。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<iostream>
#include<bitset>
#include<queue>
#include<map>
#include<stack>
#include<cmath>
#include<algorithm>
#include<vector>
#define ll long long
#define PI acos(-1.0)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define esp 1e-5
#define lowbit(x) x & (-x)
using namespace std;
const int maxx = 1e6 + 5;
const int inf = 0x3f3f3f3f;
const ll mod = 998244353;
const ll INF = 0x3f3f3f3f3f3f3f3f;
int n, m, T, N;
int a[3];
int l, r, ans;
int main(){
int i, j, k;
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1.push_back(5);
cout << "vector capacity: " << v1.capacity() << endl;
cout << "vector size: " << v1.size() << endl;;
return 0;
}
二者的区别
- resize():改变size的大小、也改变capacity的大小。容器内的对象内存空间是真正存在的。
- reserver():只改变capacity的大小。容器内的对象并没有真实的内存空间。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<iostream>
#include<bitset>
#include<queue>
#include<map>
#include<stack>
#include<cmath>
#include<algorithm>
#include<vector>
#define ll long long
#define PI acos(-1.0)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define esp 1e-5
#define lowbit(x) x & (-x)
using namespace std;
const int maxx = 1e6 + 5;
const int inf = 0x3f3f3f3f;
const ll mod = 998244353;
const ll INF = 0x3f3f3f3f3f3f3f3f;
int n, m, T, N;
int a[3];
int l, r, ans;
int main(){
int i, j, k;
vector<int> v1;
cout << "vector capacity: " << v1.capacity() << endl;
cout << "vector size: " << v1.size() << endl;
cout << "----------------------" << endl;
vector<int> v2;
v2.reserve(100);
cout << "vector capacity: " << v2.capacity() << endl;
cout << "vector size: " << v2.size() << endl;
cout << "----------------------" << endl;
vector<int> v3;
v3.resize(100);
cout << "vector capacity: " << v3.capacity() << endl;
cout << "vector size: " << v3.size() << endl;
cout << "----------------------" << endl;
vector<int> v4;
v4.push_back(1);
v4.push_back(2);
v4.push_back(3);
v4.push_back(4);
v4.push_back(5);
cout << "vector capacity: " << v4.capacity() << endl;
cout << "vector size: " << v4.size() << endl;
v4.resize(50);
cout << "vector capacity: " << v4.capacity() << endl;
cout << "vector size: " << v4.size() << endl;
return 0;
}
注意事项
-
使用 reserve()之后,此后在使用 [ ] 操作符访问容器内的对象,很可能出现数组越界的问题。要保证迭代范围小于size。
-
用[ ]访问,vector 退化为数组,不会进行越界的判断。此时推荐使用 at(),会先进行越界检查。
-
capacity 属性的容器只有 vector 和 string, list、map、set、deque这些容器的内存是散列分布的,因此不会发生类似 realloc() 的调用情况。
-
v1.resize(x),if(x < v1.size() )。则v1.size = x。多于的元素会被丢弃。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<iostream>
#include<bitset>
#include<queue>
#include<map>
#include<stack>
#include<cmath>
#include<algorithm>
#include<vector>
#define ll long long
#define PI acos(-1.0)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define esp 1e-5
#define lowbit(x) x & (-x)
using namespace std;
const int maxx = 1e6 + 5;
const int inf = 0x3f3f3f3f;
const ll mod = 998244353;
const ll INF = 0x3f3f3f3f3f3f3f3f;
int n, m, T, N;
int a[3];
int l, r, ans;
int main(){
int i, j, k;
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1.push_back(5);
cout << "vector capacity: " << v1.capacity() << endl;
cout << "vector size: " << v1.size() << endl;
for(auto i : v1){
cout << i << " ";
}
cout << endl;
v1.resize(3);
for(auto i : v1){
cout << i << " ";
}
cout << endl;
cout << "vector capacity: " << v1.capacity() << endl;
cout << "vector size: " << v1.size() << endl;
return 0;
}
- v1.resize(x),if(x > v1.size() )。则v1.size = x,添加进来的元素默认用0进行填充。【使用v1.resize(x, y),则会用y来填充】。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<iostream>
#include<bitset>
#include<queue>
#include<map>
#include<stack>
#include<cmath>
#include<algorithm>
#include<vector>
#define ll long long
#define PI acos(-1.0)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define esp 1e-5
#define lowbit(x) x & (-x)
using namespace std;
const int maxx = 1e6 + 5;
const int inf = 0x3f3f3f3f;
const ll mod = 998244353;
const ll INF = 0x3f3f3f3f3f3f3f3f;
int n, m, T, N;
int a[3];
int l, r, ans;
int main(){
int i, j, k;
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1.push_back(5);
cout << "vector capacity: " << v1.capacity() << endl;
cout << "vector size: " << v1.size() << endl;
for(auto i : v1){
cout << i << " ";
}
cout << endl;
v1.resize(7); //默认0填充
//v1.resize(7, 1)//用1进行填充
for(auto i : v1){
cout << i << " ";
}
cout << endl;
cout << "vector capacity: " << v1.capacity() << endl;
cout << "vector size: " << v1.size() << endl;
return 0;
}
- v1.resize(x),if(x > v1.capacity() )。则v1.size = x,添加进来的元素默认用0进行填充,同时会进行内存分配。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<iostream>
#include<bitset>
#include<queue>
#include<map>
#include<stack>
#include<cmath>
#include<algorithm>
#include<vector>
#define ll long long
#define PI acos(-1.0)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define esp 1e-5
#define lowbit(x) x & (-x)
using namespace std;
const int maxx = 1e6 + 5;
const int inf = 0x3f3f3f3f;
const ll mod = 998244353;
const ll INF = 0x3f3f3f3f3f3f3f3f;
int n, m, T, N;
int a[3];
int l, r, ans;
int main(){
int i, j, k;
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1.push_back(5);
cout << "vector capacity: " << v1.capacity() << endl;
cout << "vector size: " << v1.size() << endl;
for(auto i : v1){
cout << i << " ";
}
cout << endl;
v1.resize(10);
for(auto i : v1){
cout << i << " ";
}
cout << endl;
cout << "vector capacity: " << v1.capacity() << endl;
cout << "vector size: " << v1.size() << endl;
return 0;
}
vector内存分配
- vector内存分配机制:当空间不够装下数据时,会自动申请另一片更大的空间(1.5倍或者2倍),然后把原来的数据拷贝到新的内存空间,接着释放原来的那片空间【为了避免不必要的拷贝,每次可以在创建vector对象的时候指定vector的capacity】。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<iostream>
#include<bitset>
#include<queue>
#include<map>
#include<stack>
#include<cmath>
#include<algorithm>
#include<vector>
#define ll long long
#define PI acos(-1.0)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define esp 1e-5
#define lowbit(x) x & (-x)
using namespace std;
const int maxx = 1e6 + 5;
const int inf = 0x3f3f3f3f;
const ll mod = 998244353;
const ll INF = 0x3f3f3f3f3f3f3f3f;
int n, m, T, N;
int a[3];
int l, r, ans;
int main(){
int i, j, k;
vector<int> v1;
cout << "vector capacity: " << v1.capacity() << endl;
cout << "vector size: " << v1.size() << endl;
int num = 0;
int *p = NULL;
for(int i = 0; i < 100000; i++){
v1.push_back(i);
if(p != &v1[0]){
p = &v1[0];
num++;
}
}
cout << "内存分配次数:" << num << endl;
return 0;
}