C++容器内存分配特点:.

/顺序容器//

Vector:

内存申请:

vector其中一个特点:内存空间只会增长,不会减小

特点:

1、由于为了支持快速的随机访问,vector容器的元素以连续方式存放,每一个元素都紧挨着前一个元素存储。

2、因此当vector添加一个元素时,为了满足连续存放这个特性,都需要重新分配空间、拷贝元素、撤销旧空间,这样性能难以接受。

因此必须要对这个进行一些优化:C++ STL中的vector在分配内存的时候,实际分配的容量要比当前所需的空间多一些。因此,vector容器预留了一些额外的存储区,用于存放新添加的元素,这样就不必为每个新元素重新分配整个容器的内存空间。

操作函数:

push_back()

每次执行push_back操作,相当于底层的数组实现要重新分配大小;这种实现体现到vector实现就是每当push_back一个元素,都要重新分配一个大一个元素的存储,然后将原来的元素拷贝到新的存储,之后在拷贝push_back的元素,最后析构掉原有的vector并释放原有的内存。

 

内存释放:

1、由于vector的内存占用空间只增不减,比如你首先分配了10,000个字节,然后erase掉后面9,999个,留下一个有效元素,但是内存占用仍为10,000个。

2、所有内存空间是在vector析构的时候才能被系统回收。empty()用来检测容器是否为空的,clear()可以清空所有元素。但是即使clear(),vector所占用的内存空间依然如故,无法保证内存的回收。

3、释放vector内存最简单的方法是vector<T>().swap(T的变量),强制释放内存。

如下代码:

template < class T >
void ClearVector( vector< T >& vt )
{
vector< T > vtTemp;
veTemp.swap( vt );
}

注意:

1、如果vector中存放的是指针,则当vector释放掉之后这些指针所指向的内存并没有释放掉,因此需要先把这些指针所指向的内存释放掉之后在释放vector容器的内存。


String:

String 包括两种存在方式:

第一种是实体对象申请:如  string  str;这种申请方式当出了str的作用域之后就会自动释放内存;

第二种是指针对象申请:如  string  *strp = new string(“abc”),这里注意到使用new来申请内存,因此释放的时候就需要调用delete函数,c++中new和delete必须成对出现。因为这个地方如果只是把strp释放掉,并没有释放掉存储”abc”字符串的内存,只是释放了一个4B的指针内存。

 

List:

list不像vector那样,list的内存分配时非连续的,因此,只能通过迭代器来访问list中的元素。另外,list在头和尾都可以插入元素。

特点:

List由双向链表实现,每个节点存储一个元素,因为是双向链表因此支持在前后两个方向进行插入和删除操作。因此插入删除动作很快。

List不支持随机存取,因为是链表,所以必须迭代。不提供下标操作和at函数。(at函数也是下标机制只不过能提供强大的越界检查)

List实现了数据结构里的链表的所有功能,因此申请内存和释放内存都是对单个插入和删除的节点而言的。

 

Deque(双端队列)

双端队列实现在两端快速的插入和删除,提供随机访问的能力。实现了数据结构中队列的全部功能。

当需要向两端快速的插入和删除的时候最佳的是deque容器。

内存分配以动态数组的形式分配。

1、其大部分函数和vector类似,主要差别在于:

2、Deque可以操作两端,而vector只可以操作一端,插入和删除。

存取元素的时候,deque会稍慢一些,这一点应该用队列的知识来解释,vector是数组,直接定位到数据,而deque是队列,因此如果存取中间的元素会很麻烦。而且要先出队列,然后在入队列,而vector不需要这样做。




/关联容器//

Set:

顺序存储一组值是set等集合型容器的特点。其中的元素既可以充当存储的数据,也可以充当数据的关键码。

特点:

1、set集合容器:实现了红黑树的平衡二叉检索树的数据结构。插入元素时,它会自动调整二叉树的排列,把元素放到适当的位置,以保证每个子树根节点键值大于左子树所有节点的键值,小于右子树所有节点的键值;另外,还得保证根节点左子树的高度与右子树高度相等。

2、平衡二叉检索树使用中序遍历算法,检索效率高于vector、deque和list等容器,另外使用中序遍历可将键值按照从小到大遍历出来。
构造set集合主要目的是为了快速检索,不可直接去修改键值。

 

Multiset:

set和multiset会根据特定的排序准则,自动将元素进行排序。不同的是后者允许元素重复而前者不允许。


Map:

map是一类关联式容器,它是模板类。关联的本质在于元素的值与某个特定的键相关联,而并非通过元素在数组中的位置类获取。它的特点是增加和删除节点对迭代器的影响很小,除了操作节点,对其他的节点都没有什么影响。对于迭代器来说,不可以修改键值,只能修改其对应的实值。

MultiMap