一、 resize和reserve
resize就是重新分配大小,reserve就是预留一定的空间。这两个接口即存在差别,也有共同点。下面就它们的细节进行分析。
为实现resize的语义,resize接口做了两个保证:
一是保证区间[0, new_size)范围内数据有效,如果下标index在此区间内,vector[indext]是合法的。
二是保证区间[0, new_size)范围以外数据无效,如果下标index在区间外,vector[indext]是非法的。
reserve只是保证vector的空间大小(capacity)最少达到它的参数所指定的大小n。在区间[0, n)范围内,如果下标是index,vector[index]这种访问有可能是合法的,也有可能是非法的,视具体情况而定。
resize和reserve接口的共同点是它们都保证了vector的空间大小(capacity)最少达到它的参数所指定的大小。
因两接口的源代码相当精简,以至于可以在这里贴上它们:
void resize(size_type new_size) { resize(new_size, T()); }
void resize(size_type new_size, const T& x) {
if (new_size < size())
erase(begin() + new_size, end()); // erase区间范围以外的数据,确保区间以外的数据无效
else
insert(end(), new_size - size(), x); // 填补区间范围内空缺的数据,确保区间内的数据有效
}
void reserve(size_type n) {
if (capacity() < n) {
const size_type old_size = size();
iterator tmp = allocate_and_copy(n, start, finish);
destroy(start, finish);
deallocate();
start = tmp;
finish = tmp + old_size;
end_of_storage = start + n;
}
}
二、http://topic.youkuaiyun.com/t/20050121/10/3742864.html
vector在push_back的时候,如果空间不足,会自动增补一些空间,如果没有预留的空间可用
就直接申请另一块可用的连续的空间,把数据拷贝过去,然后删除旧空间,使用新空间
结果造成效率低下
如果在事先预见到有较大空间需求,就可以先用reserve预留一定的空间,避免内存重复分配和
大量的数据搬移。提高了效率
size指的是除去预留的额外空间的所有用来存放数据的空间,resize也好理解,如果说你对某部分
没有进行初始化(比如原本的size是100,现在resize为200个),那就给其余100个调用默认构造函数,
如果是内置类型,初始化为0——我对初始化内置类型这点不是特别肯定,你可以查资料).
capacity返回的是包括预留的空间在内的所有空间大小,通常跟reserve的那个大小相当,否则根据分配策略获得。capacity的正式定义为:在不需要重新分配空间的情况下,vector能容纳的元素的最大数量
举例说:
vector <int> v;
v.reserve(16);
assert(v.capacity()==16);
vector <int> v;
cout < < v.capacity(); //这里就依赖于库的实现,
三、resize()/reserve(), size()/capacity()
http://blog.youkuaiyun.com/sodickbird/article/details/4594907
Q1. 当前容器有多少个元素?
Q2. 怎样重设容器的元素个数?
A1: You know, 所有的STL容器都提供了size()这个操作函数,返回当前容器的元素个数. (参考 C++标准程序库自修教程与参考手册 P146).
A2: vector, deque和list都提供了resize()这个函数来重设元素个数. 对于新增加的元素怎么初始化,resize通过第2个参数说明.
好了, size()和resize()清楚后,再来看看 reserve()和capacity(), 他是vector特有的,也是由vector的特性所决定的.
我们都知道, vector是在内存中是连续分布的,所以设计上总会在所有已经有元素外预留一些空间,否则每次追加新元素时都要再次分配内存,那准备就绪将很低.
假如当vector中可能会存在约500个元素时, 比较两种做法:
1. vector<int> myVec, 然后500次调用 myVec.push_back(****)
2. vector<int> myVec(500), 然后500次调用 myVec.push_back(****)
做法2只需要进行1到2次内存分配,而做法1不知道要进行多少次内存分配了.
现在, 同样,两个问题:
Q1. 当前容器预留了多大空间(在不进行重新分配内存的前提下,最多可以容纳多少个元素)?
Q2. 怎样重设当前容器的预留大小?
A1: capacity().
A2: reserve().
辨析:
所以说resize()和reserve根本是两回事,resize影响元素的个数. reserve只分配预留的空间.
所以 capacity() >= size() 恒成立.
另外有几个问题:
1. vector<int> a(10); a.reserve(20); a[10] = 999; // 错误, 因为a还没有下标为10这个元素,现在size() ==10, capacity() ==20; 要追加下标10这个元素只能push_back;
2. 假设vector<int> sample;
当前size()为50, capacity()为100,经过以下操作:
(1) resize(10). //size() == 10; 10到49下标的元素被删除. capacity()==100,不变,没有进行内存重新分配.
(2) resize(60). //size() == 60; 50到59下标用默认构造函数填充. capacity() == 100,不变,没有进行内存重新分配.
(3) resize(60, 9999). //size() == 60; 50到59下标用9999填充. capacity() == 100,不变,没有进行内存重新分配.
(4) resize(200). //size() == 200; 50到199下载用默认构造函数填充. capacity() == 200, 自动扩容,重新分配内存.
(5) reserve(10). //size() == 50; 不变,没有元素被删除, capacity() == 100, 不变. 即reserve调用没起作用.
(6) reserve(60). //size() == 50; 元素没有变, capacity() == 100, 不变. 即reserve调用没起作用.
(7) reserve(200). //size() == 50; 元素没有变, capacity() == 200, 扩容,重新分配内存.
3. vector<int> sample(10); //size() == 10; reserve() == 10;
sample.push_back(999); //size() == 11; reserve () == 15; //自动扩容, reseve为什么不是11呢? 这个超余量是不一定的,也不一定是15.
resize就是重新分配大小,reserve就是预留一定的空间。这两个接口即存在差别,也有共同点。下面就它们的细节进行分析。
为实现resize的语义,resize接口做了两个保证:
一是保证区间[0, new_size)范围内数据有效,如果下标index在此区间内,vector[indext]是合法的。
二是保证区间[0, new_size)范围以外数据无效,如果下标index在区间外,vector[indext]是非法的。
reserve只是保证vector的空间大小(capacity)最少达到它的参数所指定的大小n。在区间[0, n)范围内,如果下标是index,vector[index]这种访问有可能是合法的,也有可能是非法的,视具体情况而定。
resize和reserve接口的共同点是它们都保证了vector的空间大小(capacity)最少达到它的参数所指定的大小。
因两接口的源代码相当精简,以至于可以在这里贴上它们:
void resize(size_type new_size) { resize(new_size, T()); }
void resize(size_type new_size, const T& x) {
if (new_size < size())
erase(begin() + new_size, end()); // erase区间范围以外的数据,确保区间以外的数据无效
else
insert(end(), new_size - size(), x); // 填补区间范围内空缺的数据,确保区间内的数据有效
}
void reserve(size_type n) {
if (capacity() < n) {
const size_type old_size = size();
iterator tmp = allocate_and_copy(n, start, finish);
destroy(start, finish);
deallocate();
start = tmp;
finish = tmp + old_size;
end_of_storage = start + n;
}
}
二、http://topic.youkuaiyun.com/t/20050121/10/3742864.html
vector在push_back的时候,如果空间不足,会自动增补一些空间,如果没有预留的空间可用
就直接申请另一块可用的连续的空间,把数据拷贝过去,然后删除旧空间,使用新空间
结果造成效率低下
如果在事先预见到有较大空间需求,就可以先用reserve预留一定的空间,避免内存重复分配和
大量的数据搬移。提高了效率
size指的是除去预留的额外空间的所有用来存放数据的空间,resize也好理解,如果说你对某部分
没有进行初始化(比如原本的size是100,现在resize为200个),那就给其余100个调用默认构造函数,
如果是内置类型,初始化为0——我对初始化内置类型这点不是特别肯定,你可以查资料).
capacity返回的是包括预留的空间在内的所有空间大小,通常跟reserve的那个大小相当,否则根据分配策略获得。capacity的正式定义为:在不需要重新分配空间的情况下,vector能容纳的元素的最大数量
举例说:
vector <int> v;
v.reserve(16);
assert(v.capacity()==16);
vector <int> v;
cout < < v.capacity(); //这里就依赖于库的实现,
三、resize()/reserve(), size()/capacity()
http://blog.youkuaiyun.com/sodickbird/article/details/4594907
Q1. 当前容器有多少个元素?
Q2. 怎样重设容器的元素个数?
A1: You know, 所有的STL容器都提供了size()这个操作函数,返回当前容器的元素个数. (参考 C++标准程序库自修教程与参考手册 P146).
A2: vector, deque和list都提供了resize()这个函数来重设元素个数. 对于新增加的元素怎么初始化,resize通过第2个参数说明.
好了, size()和resize()清楚后,再来看看 reserve()和capacity(), 他是vector特有的,也是由vector的特性所决定的.
我们都知道, vector是在内存中是连续分布的,所以设计上总会在所有已经有元素外预留一些空间,否则每次追加新元素时都要再次分配内存,那准备就绪将很低.
假如当vector中可能会存在约500个元素时, 比较两种做法:
1. vector<int> myVec, 然后500次调用 myVec.push_back(****)
2. vector<int> myVec(500), 然后500次调用 myVec.push_back(****)
做法2只需要进行1到2次内存分配,而做法1不知道要进行多少次内存分配了.
现在, 同样,两个问题:
Q1. 当前容器预留了多大空间(在不进行重新分配内存的前提下,最多可以容纳多少个元素)?
Q2. 怎样重设当前容器的预留大小?
A1: capacity().
A2: reserve().
辨析:
所以说resize()和reserve根本是两回事,resize影响元素的个数. reserve只分配预留的空间.
所以 capacity() >= size() 恒成立.
另外有几个问题:
1. vector<int> a(10); a.reserve(20); a[10] = 999; // 错误, 因为a还没有下标为10这个元素,现在size() ==10, capacity() ==20; 要追加下标10这个元素只能push_back;
2. 假设vector<int> sample;
当前size()为50, capacity()为100,经过以下操作:
(1) resize(10). //size() == 10; 10到49下标的元素被删除. capacity()==100,不变,没有进行内存重新分配.
(2) resize(60). //size() == 60; 50到59下标用默认构造函数填充. capacity() == 100,不变,没有进行内存重新分配.
(3) resize(60, 9999). //size() == 60; 50到59下标用9999填充. capacity() == 100,不变,没有进行内存重新分配.
(4) resize(200). //size() == 200; 50到199下载用默认构造函数填充. capacity() == 200, 自动扩容,重新分配内存.
(5) reserve(10). //size() == 50; 不变,没有元素被删除, capacity() == 100, 不变. 即reserve调用没起作用.
(6) reserve(60). //size() == 50; 元素没有变, capacity() == 100, 不变. 即reserve调用没起作用.
(7) reserve(200). //size() == 50; 元素没有变, capacity() == 200, 扩容,重新分配内存.
3. vector<int> sample(10); //size() == 10; reserve() == 10;
sample.push_back(999); //size() == 11; reserve () == 15; //自动扩容, reseve为什么不是11呢? 这个超余量是不一定的,也不一定是15.