vector和deque的底层区别

1、vector

vector概述

vector的数据安排以及操作方式,与array非常相似。两者的唯一差别在于空间的运用的灵活性。array是静态空间,一旦配置了就不能改变;要换个大(或小)一点的房子,可以,一切琐细得由客户端自己来:首先配置一块新空间,然后将元素从旧址一一搬往新址,再把原来的空间释还给系统。vector是动态空间,随着元素的加入,它的内部机制会自行扩充空间以容纳新元素。因此,,vector的运用对于内存的合理利用与运用的灵活性有很大的帮助,我们再也不必因为害怕空间不足而,一开始就要求一个大块头array了,我们可以安心使用vector,吃多少用多少。

vector的数据结构

vector所采用的数据结构非常简单:线性线性空间。它以两个迭代器start和finish分别指向配置得来的连续空间中目前已经被使用的范围,并以迭代器end_of_storage指向整块连续空间的尾端:

template<class T, class Alloc = alloc>
class vector {
...
protected:
    iterator start;             //表示目前使用空间的头
    iterator finish;            //表示目前使用空间的尾
    iterator end_of_storage;    //表示目前可用空间的尾
};

为了降低空间配置时的速度成本,vector实际配置的大小可能比客户端需求更大一些,以备将来可能的扩充。

vector的构造与内存管理

当我们以push_back()将新元素插入vector尾端时,该函数首先检查是否还有备用空间,如果有就直接在备用空间上构造元素,并调整迭代器finish,使vector变大。如果没有备用空间了,就扩充空间(重新配置、移动数据、释放原空间)。

注意:所谓动态增加大小,并不是在原空间之后接续新空间,而是以原大小的两倍另外配置一块较大空间,然后将原内容拷贝过来,然后才开始在原内容之后构造新元素,并释放原空间。因此,对vector的任何操作,一旦引起空间的重新配置,指向原vector的所有迭代器就都失效了。

2、deque

deque概述

deque是一种双向开口的连续线性空间。所谓双向开口,意思是可以在头尾两端分别做元素的插入和删除操作。

deque的中控器

deque系由一段一段的定量连续空间构成。一旦有必要在deque的前端或尾端增加新空间,便配置一段定量连续空间,串接在整个deque的头端或尾端。deque的最大任务,便是在这些分段的定量连续空间上,维护其整体连续的假象,并提供随机存取的接口。避开了“重新配置、复制、释放”的轮回,代价则是复杂的迭代器架构。

deque采用一块所谓的map(注意,不是STL的map容器)作为主控。这里所谓map是一小块连续空间 ,其中每个元素(此处称为一个节点, node)都是指针,指向另一段(较大的) 连续线性空间,称为缓冲区。缓冲区才是deque的存储空间主体。

template <class T, class Allod  alloc, size_t Bufsiz = 0>
class deque {
public:
    typedef T value_type;
    typedef value_type* pointer;
    ...
protected:
    typedef pointer* map pointer;

protected:
    map_pointer map;//指向map,map是块连续空间,其内的每个元素都是一个指针,指向一块缓冲区
    size_type map_size;//map可容纳多少指针
...
}

这里写图片描述

deque的构造与内存管理

如果申请的map空间不够时,也需要重新配置更大的空间,将原来map里的指针拷贝过来,最后释放原来的空间。

3、vector和deque的区别

  • vector是单向开口的连续线性空间, dequeu是一种双向开口的连续线性定 ;
  • deque允许于常数时间内对起头端进行元素的插入或移除操作 ;
  • deque没有所谓容量(capacity)观念,因为它是动态地以分段连续空间组合而成,随时可以增加一段新的空间并链接起来

4、参考资料

侯捷著《STL源码剖析》

猜你喜欢

转载自blog.csdn.net/chen134225/article/details/81744367
今日推荐