旅途

如果想飞得高,就该把地平线忘掉

vector内存管理

为了提高效率,实际上vector 并不是随每一个元素的插入而增长自己,而是当vector 需
要增长自身时,它实际分配的空间比当前所需的空间要多一些.。也就是说它分配了一些额
外的内存容量或者说它预留了这些存储区分配的额外容量的确切数目由具体实现定义,
这个策略使容器的增长效率更高——因此实际上对于小的对象vector 在实践中比list
效率更高
让我们来看一看在C++标准库的Rogue Wave 实现版本下的一些例子但是首先
我们要弄清楚容器的容量和长度size 之间的区别。
容量是指在容器下一次需要增长自己之前能够被加入到容器中的元素的总数,容量只与
连续存储的容器相关,例如vector deque 或string ,list 不要求容量。为了知道一个容器的
容量我们调用它的capacity()操作而长度size 是指容器当前拥有元素的个数为了获
得容器的当前长度我们调用它的size()操作例。

我在VC++.net上试验的代码,可以看出他的增长方式

   FILE *file=freopen("1.txt","w",stdout);
   vector<int> vec;
   cout<<"capacity"<<vec.capacity()<<"size"<<vec.size()<<endl;
   for(int i=0;i<100;i++)
   {
      vec.push_back(i);
   cout<<"capacity"<<vec.capacity()<<"size"<<vec.size()<<endl;
   }


结果如下:
capacity0size0
capacity1size1
capacity2size2
capacity3size3
capacity4size4
capacity6size5
capacity6size6
capacity9size7
capacity9size8
capacity9size9
capacity13size10
capacity13size11
capacity13size12
capacity13size13
capacity19size14
capacity19size15
capacity19size16
capacity19size17
capacity19size18
capacity19size19
capacity28size20
capacity28size21
capacity28size22
capacity28size23
capacity28size24
capacity28size25
capacity28size26
capacity28size27
capacity28size28
capacity42size29
capacity42size30
capacity42size31
capacity42size32
capacity42size33
capacity42size34
capacity42size35
capacity42size36
capacity42size37
capacity42size38
capacity42size39
capacity42size40
capacity42size41
capacity42size42
capacity63size43
capacity63size44
capacity63size45
capacity63size46
capacity63size47
capacity63size48
capacity63size49
capacity63size50
capacity63size51
capacity63size52
capacity63size53
capacity63size54
capacity63size55
capacity63size56
capacity63size57
capacity63size58
capacity63size59
capacity63size60
capacity63size61
capacity63size62
capacity63size63
capacity94size64
capacity94size65
capacity94size66
capacity94size67
capacity94size68
capacity94size69
capacity94size70
capacity94size71
capacity94size72
capacity94size73
capacity94size74
capacity94size75
capacity94size76
capacity94size77
capacity94size78
capacity94size79
capacity94size80
capacity94size81
capacity94size82
capacity94size83
capacity94size84
capacity94size85
capacity94size86
capacity94size87
capacity94size88
capacity94size89
capacity94size90
capacity94size91
capacity94size92
capacity94size93
capacity94size94
capacity141size95
capacity141size96
capacity141size97
capacity141size98
capacity141size99
capacity141size100

对于小的数据类型vector 的性能要比list 好得多,而对于大型的数据类型则相反list 的性能要好得多,区别是由于vector 需要重新增长以及拷贝元素。

无论是list 还是vector ,对于已定义拷贝构造函数的类来说插入这样的类的元素都需要调用拷贝构造函数拷贝构造函数(用该类型的一个对象初始化该类型的另一个对象)

这正说明了在简单类和string 的链表之间插入代价的区别:简单类对象和大型简单类对象通过按位拷贝插入一个对象的所有位被拷贝到第二个对象的位中,而string 类对象和大型复杂类对象通过调用拷贝构造函数来插入。

另外随着每次重新分配内存,vector 必须为每个元素调用拷贝构造函数,而且在释放原来的内存时它要为每个元素调用其相关类型的析构函数。vector 的动态自我增长越频繁,元素插入的开销就越大。

当然,一种解决方案是,当vector 的开销变得非常大时把vector 转换成list ;另一种经
常使用的方案是通过指针间接存储复杂的类对象。

posted on 2007-09-20 15:15 旅途 阅读(5637) 评论(0)  编辑 收藏 引用 所属分类: C++ STL


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理