vector是一种序列式容器,所谓序列式容器,即其中的元素可以排序,但是并未排序。可以把vector可作为加强版的array,它和array一样,存储空间是一段连续的内存,因此支持随机访问,但是,和array相比,vector支持动态增加数据。 vector支持动态增加数据,同时又需要保持空间的连续性从而支持随机访问,因此,在对vector动态增加元素时,如果旧有空间装满,需要申请更大的内存,并且需要把旧有数据搬到新内存去,因此,数据的搬移效率使我们在开发过程中需要考虑的重要因素。
API
size : returns the number of elements 返回vector中元素的个数
capacity: returns the number of elements that can be held in currently allocated storage 返回vector分配的存储空间的大小
resize: changes the number of elements stored 。创建元素,空间不足的时候会申请内存
reserve:reserves storage 预留内存,但是不会创建元素。
vector的内存分配是当空间不足时,则按照当前空间2倍大小来申请空间。然后将原来的数据拷贝到新空间,释放原空间。
void capacity_test() {
printf("*********%s********\n", __FUNCTION__);
std::vector<A> vec;
printf("size:%u, cap:%d\n", vec.size(), vec.capacity());
for (int i = 0; i < 4; ++i) {
vec.push_back(A());
printf("size:%u, cap:%d\n", vec.size(), vec.capacity());
}
printf("*********%s********\n", __FUNCTION__);
}
resize 源码:
注意resize是构造一个对象传入,所以会调用一次构造。然后再调用void resize(size_type new_size, const T& x) 函数,这里调用拷贝构造。然后根据空间大小决定是insert还是erase。
void resize(size_type new_size, const T& x)
{
if (new_size < size())
erase(begin() + new_size, end());
else
insert(end(), new_size - size(), x);
}
void resize(size_type new_size) { resize(new_size, T()); }
插入的源码如下:
template <class T, class Alloc>
void vector<T, Alloc>::insert(iterator position, size_type n, const T& x)
{
// 如果n为0则不进行任何操作
if (n != 0) {
if (size_type(end_of_storage - finish) >= n) { // 剩下的内存够分配
T x_copy = x;
const size_type elems_after = finish - position;
iterator old_finish = finish;
if (elems_after > n) {
uninitialized_copy(finish - n, finish, finish);
finish += n;
copy_backward(position, old_finish - n, old_finish);
fill(position, position + n, x_copy);
}
else {
uninitialized_fill_n(finish, n - elems_after, x_copy);
finish += n - elems_after;
uninitialized_copy(position, old_finish, finish);
finish += elems_after;
fill(position, old_finish, x_copy);
}
}
else { // 剩下的内存不够分配, 需要重新分配
const size_type old_size = size();
const size_type len = old_size + max(old_size, n);
iterator new_start = data_allocator::allocate(len);
iterator new_finish = new_start;
__STL_TRY {
new_finish = uninitialized_copy(start, position, new_start);
new_finish = uninitialized_fill_n(new_finish, n, x);
new_finish = uninitialized_copy(position, finish, new_finish);
}
# ifdef __STL_USE_EXCEPTIONS
catch(...) {
destroy(new_start, new_finish);
data_allocator::deallocate(new_start, len);
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
destroy(start, finish);
deallocate();
start = new_start;
finish = new_finish;
end_of_storage = new_start + len;
}
}
}
注意这里的问题就是如果vector开始的时候没有预留空间,则在插入的元素时,就可能导致多次重新申请空间,分配内存。