首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

为什么vector有了resize函数还要提供一个reserve函数?该怎么解决

2012-05-06 
为什么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,则都会改变。。








探讨

两个不同功能的函数啊,一个影响里面时间元素的个数总数,一个影响vector的容量,这个完全是两个不同的概念

[解决办法]
谁说的,代码呢??


探讨

数组没有初始化,可以直接赋值。

为什么vector的空间预留了,不能直接使用呢?

那还要预留这个函数做什么用?

[解决办法]
resize内部调用了_Reserve函数,而_Reserve函数内部又调用了reserve函数,所以最后还是可能分配空间的。

合理地调用reserve函数可以加快程序运行效率,避免频繁加入元素时引起的多次重新分配内存。

对象数组内容是必须初始化的,只是隐式调用了,你没有注意到。而原生简单类型数组没有生成默认初始化代码。

虽然你调用了reserve预留了空间,但是在读取的时候出错是因为vector的代码对你的下标进行了检查,不允许访问尚未初始化过的空间(即使空间已经分配)。
------解决方案--------------------


看9 楼,sgi版本呢


探讨

resize内部调用了_Reserve函数,而_Reserve函数内部又调用了reserve函数,所以最后还是可能分配空间的。

合理地调用reserve函数可以加快程序运行效率,避免频繁加入元素时引起的多次重新分配内存。

对象数组内容是必须初始化的,只是隐式调用了,你没有注意到。而原生简单类型数组没有生成默认初始化代码。

虽然你调用了reserve预留了空间,但是在读取的时候出……

[解决办法]
reserve函数主要是为提升vector的效率而存在的,如果已知vector的大小,可以在初始化时为vector执行reserve操作,分配足够的内存空间,之后数据加入vector就不会造成内存再次分配,也可以减少内存碎片。另外reserve操作只分配内存空间,并不执行元素初始化,因此效率上要比resize要高,假如vector中存储的是复杂的对象,执行这些元素的初始化将是一笔不小的开销。
[解决办法]
楼主试下下面两段代码的性能差别,立马就知道reserve函数的功能了:
C/C++ code
vector<int> v;for(int i=0; i<100000; ++i)  v.push_back(i); 

热点排行