我这里不是将他们的区别,主要讲使用他们时要注意的一些问题,主要体现在内存方面。
C++中,我们很少使用C中的数组,使用数组就意味着承担:
- new一个数组以后,必须保证有delete来删除所分配的内存。最好是指针句柄可以*p=NULL。
- 必须使用正确的delete,单个对象分配内存时使用delete,多个对象分配内存时使用delete[ ]。
- 一个对象必须只被delete了一次,多次会出现意想不到的错误。
当然,这些是比起数组的缺点,vector的优势所在就是上面的都不用考虑了,不过这不是我今天的重点,了解一下也是蛮有滋味的。string中有个引用计数的问题,也是本文的重点。
一、对于vector和string,每当需要更多内存空间时,就调用和realloc类似的操作,分4步实现:
- 分配一块大小为当前容量的某个倍数的心内存,大多数情况下是2倍。
- 把容器中的所有元素从旧的内存复制到新的内存中
- 析构掉旧内存中的对象
- 释放旧内存
看到这里如果你觉得很繁琐,效率不高,那就对了,这么好的东西也是有不足的,尤其是当这些过程发生时,vector和string中的所有指针、迭代器还有引用都将变得无效,我可不是什么好事。但是我们为什么觉得他们好。reserve就是解决这一问题出现的。这之前我们看看4个函数
- size()告诉我们容器中有多少个元素,但不会告诉我们容器可以容纳多少个元素。
- capacity()该容器已经分配的内存可以容纳多少个元素,也就是容器可以容纳的总元素个数。如果想知道一个容器还有多少内存可以使用,那capacity()-size()就知道了。
- resize(Container::size_type n)强迫容器改变到含有n个元素的状态,返回值是n。如果n比当前的容量小,就析构掉容器尾部的元素。如果大于当前容量就重新分配内存
- reserve(Container::size_type n)强迫容器把它的容量变为至少n,如果n大于当前容量就变为n,小于则不变,vector直接忽略该函数,不调用,string一般用swap技巧实现内存的释放。
关于string的引用计数string引用计数。好事多磨,我继续学习去了!