zoukankan      html  css  js  c++  java
  • STL总结之deque

    STL中deque是我们常说的双端队列,既可以从头添加元素,也可以从尾部添加元素,deque的成员函数和vector的成员函数十分相似,但是它们的内部实现却又很多不同.
     
    deque的模板声明:
    template < class T, class Allocator = allocator< T> > class deque;
     
    1)deque的内存分配方式,deque的内存管理方式比vector复杂.
     
    上面程序在执行完最后的push_back后内存分布如下图:
     
     
    追踪push_back函数我们看到:
    我们先看几个变量的含义, _Myoff成员变量始终表示队头距离存储空间开始位置的元素个数, _DEQUESIZ宏定义如下,可以看到为了避免太小内存块,_DEQUESIZ会根据我们定义类型大小来确定一个block大小.
    _Mysize表示队列中实际元素个数,_Map是一个_Ty**类型二级指针,正是挂接block的chunk, 宏_DEQUEMAPSIZ正是_Map的最小分配粒度.
    如果存储空间不足时_DEQUESIZ我们要进行内存分配, 可以看到程序根据_Myoff和_Mysize来计算block编号,因此我们可以把_Map看成是一个环,而所有的block也可以看成一个环.在前面计算好block后,
    判断该block是否已经分配内存,如果没有则分配内存,如果有则直接对新添加的对象在分配的内存中进行构造.
     
    下面我们看下_Growmap函数,这里我做了简化,把copy数据的过程去掉了,我们可以看到在我们重新分配内存大小是以原来chunk大小的一半进行增加,如果增加大小小于最小粒度_DEQUEMAPSIZ,则取最小粒度,
    如果用户需求大于我们计算的值,则以用户需求值进行增加,然后释放原来_Map的空间.
     
    其他push_front操作和push_back操作类似,只是在计算block位置是不一样, 如下:
     
     
    2)deque其他操作,pop_front和pop_back时只是将队头和队尾元素移除,进行insert操作时有点复杂,我们看看插入在一个位置插入多个元素的情况.
    上面列出了靠近队头位置时的处理情况,靠近队尾时情况差不多,这里不再贴出,insert的其他重载函数操作类似.
     
    deque在进行erase进行移除元素时,要比insert操作简单多了,如下:
     
    deque的clear操作和vector不一样,这里clear的话是直接将内存释放掉了.
     
    总结:deque在进行内存管理上更复杂,但与vector比较内存管理更加有效,特别是对大量数据序列,不过我们可以看到内存在根据我们的需求不断申请,但是没有释放,如果在数据量波动比较大的地方,可能比较消耗内存,
    不过我们可以使用clear函数将内存释放掉,我想clear这么做肯定是考虑到了这个需求.
     
     
     
     
     
  • 相关阅读:
    ArcEngine9.3没有原生支持64位,而是以32位兼容方式运行
    记一次IIS应用程序域崩溃的原因
    切换添加[置顶] Behaviors扩展根据Pivot的item自动切换AppBar
    参数类型11g_job执行带参数的procedure
    元素返回[Python]python算法入门 栈(stack)
    模型案例复杂性思考
    执行目录glassfish不能远程登录问题
    文件目录IBM的LPI复习资料之LPI101Topic103 :GNU和Unix命令(3)文件和目录管理
    企业网站[正能量系列]失业的程序员(一)
    缓冲区方法你有被stringstream坑过吗?
  • 原文地址:https://www.cnblogs.com/ourroad/p/3356053.html
Copyright © 2011-2022 走看看