为什么vector有了resize函数还要提供一个reserve函数?感觉reserve函数本身没有什么作用啊,reserve出来的空
为什么vector有了resize函数还要提供一个reserve函数?
感觉reserve函数本身没有什么作用啊,reserve出来的空间并不能使用:
vector<int> vi;
vi.reserve(3);
//vi.resize(3);
vi[2]=88;//程序在这里会崩溃。
我在VC和GCC下面试了都不行。VC的源代码我查看了一下,reserve函数里面也调用到了alloc,而可以工作的resize函数反而不包含alloc调用,和我期待的相反。
这是为什么呢? vector提供reserve这个函数,reserve出来的空间又不能用。那么什么时候需要reserve呢?
我似乎觉得有resize就可以了呀。请指点!
C/C++ code void reserve(size_type _Count) { // determine new minimum length of allocated storage if (max_size() < _Count) _Xlen(); // result too long else if (capacity() < _Count) { // not enough room, reallocate pointer _Ptr = this->_Alval.allocate(_Count); _TRY_BEGIN _Umove(this->_Myfirst, this->_Mylast, _Ptr); _CATCH_ALL this->_Alval.deallocate(_Ptr, _Count); _RERAISE; _CATCH_END size_type _Size = size(); if (this->_Myfirst != 0) { // destroy and deallocate old array _Destroy(this->_Myfirst, this->_Mylast); this->_Alval.deallocate(this->_Myfirst, this->_Myend - this->_Myfirst); } this->_Orphan_all(); this->_Myend = _Ptr + _Count; this->_Mylast = _Ptr + _Size; this->_Myfirst = _Ptr; } }-------------------------------- void resize(size_type _Newsize) { // determine new length, padding with _Ty() elements as needed if (_Newsize < size()) erase(begin() + _Newsize, end()); else if (size() < _Newsize) { // pad as needed _Reserve(_Newsize - size()); _Uninitialized_default_fill_n(this->_Mylast, _Newsize - size(), (_Ty *)0, this->_Alval); this->_Mylast += _Newsize - size(); } }
[解决办法]reserve是容器预留空间,但在空间内不真正创建元素对象,所以在没有添加新的对象之前,不能引用容器内的元素。加入新的元素时,要调用push_back()/insert()函数。
[解决办法]两个不同功能的函数啊,一个影响里面时间元素的个数总数,一个影响vector的容量,这个完全是两个不同的概念
[解决办法]3l 不完全对
resrve是都改变,看代码:
vector<T, Alloc>& operator=(const vector<T, Alloc>& 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;
}
}
resize是 内部有erase, insert操作,都可能改变capacity, size.
rserve如果预留小于当前的容量,那么不会做什么
当时resize,则都会改变。。
[解决办法]谁说的,代码呢??
[解决办法]resize内部调用了_Reserve函数,而_Reserve函数内部又调用了reserve函数,所以最后还是可能分配空间的。
合理地调用reserve函数可以加快程序运行效率,避免频繁加入元素时引起的多次重新分配内存。
对象数组内容是必须初始化的,只是隐式调用了,你没有注意到。而原生简单类型数组没有生成默认初始化代码。
虽然你调用了reserve预留了空间,但是在读取的时候出错是因为vector的代码对你的下标进行了检查,不允许访问尚未初始化过的空间(即使空间已经分配)。
------解决方案--------------------
看9 楼,sgi版本呢
[解决办法]reserve函数主要是为提升vector的效率而存在的,如果已知vector的大小,可以在初始化时为vector执行reserve操作,分配足够的内存空间,之后数据加入vector就不会造成内存再次分配,也可以减少内存碎片。另外reserve操作只分配内存空间,并不执行元素初始化,因此效率上要比resize要高,假如vector中存储的是复杂的对象,执行这些元素的初始化将是一笔不小的开销。
[解决办法]楼主试下下面两段代码的性能差别,立马就知道reserve函数的功能了:
C/C++ codevector<int> v;for(int i=0; i<100000; ++i) v.push_back(i);