STL之vector

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开始的时候没有预留空间,则在插入的元素时,就可能导致多次重新申请空间,分配内存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值