首页 > 基础资料 博客日记
C++中STL的vector扩容机制
2024-02-24 21:59:31基础资料围观525次
前言
前阵子面试的时候,被问到往vector中插入一个数据可能会发生什么?
我答:可能会扩容;
为啥vector支持变长?
我答:它实在堆上动态申请内存,因此有自己的一套扩容机制,可以操作内存大小;
它有size()和capacity()记录当前的有效元素个数和容量, 还有配套的resize()管理实际存放元素个数接口 和 reserve()管理容量接口;
下面我们详解;
发生扩容
vector作为STL的常用容器之一,其特性和数组类似,拥有一段连续的内存空间。vector申请的是一段连续的内存,**当插入新的元素内存不够时,通常会再重新申请更大的一块内存,将原来的元素拷贝过去,释放旧空间。**因为内存空间是连续的,所以在进行插入和删除操作时,会造成整体内存块的拷贝,时间复杂度为O(n)。
扩容机制
size()和capacity()
不同编译器在vector的扩容策略上显然不太一致,在vector的size()(当前容器所用的空间) 等于capacity()(当前容器总空间)时,再次插入一个元素就会发生扩容。
vs编译器每次是以1.5倍且向下取整的策略进行扩容,gcc编译器则是每次以2.0倍的策略进行扩容。(注意,初始size和capacity是0,在0的基础上第一次进行扩容的时候取第一次插入元素的个数!)
size()和capacity()是俩成员函数,vector中并没有直接存int size 和 capacity,存的其实是有效数据的始末地址和容量结尾地址
通过源码分析有三个指针:
start和finish和end_of_storage,他们三个指针用减法能算出来逻辑上的int size和int capacity数量;
reserve()和resize()
-
reserve()来改变capacity()容量的大小,是预留容器空间;
-
resize()改变size(),是有效存储元素个数;
通过源码分析:
reserve(int n)
void reserve(size_type __n){
if (__n > max_size()){
__throw_length_error(__N("vector::reserve"));
}
if (capacity() < __n){
_M_reallocate(__n);
}
}
调整capacity, 存在if判断,当n>当前capacity才有效,否则什么事都不发生;
resize(int n)
void resize(size_type __new_size){
if (__new_size > size()){
_M_default_append(__new_size - size());
}
else if (__new_size < size()){
_M_erase_at_end(this->_M_impl._M_start + __new_size);
}
}
调整size:
当size>=capacity时,capacity和size都扩容到size大小,多出来的有效元素补上缺省值(int为0);
当 size<capacity,释放多余的元素,size缩减到指定大小,capacity不变;
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
标签:
相关文章
最新发布
- springboot~3.x项目中使用集成测试
- Java测试类、工具类与JavaBean对比解析
- SpringBoot-日志
- springboot~http2的支持
- 解疑释惑 - 日志体系之 slf4j + logback 组合(一)
- Web server failed to start. Port 8080 was already in use. 端口被占用
- Springboot 项目配置多数据源
- 伙伴匹配系统(移动端 H5 网站(APP 风格)基于Spring Boot 后端 + Vue3 - 05
- 剑指offer-23、搜索⼆叉树的后序遍历序列
- 一个表示金额的数字是 100000000L,这是多少米?