C++中STL的vector扩容机制

news/2024/11/17 7:21:54/

目录

    • 前言
    • 发生扩容
    • 扩容机制
      • size()和capacity()
      • reserve()和resize()

前言

前阵子面试的时候,被问到往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不变;


http://www.ppmy.cn/news/8432.html

相关文章

保护性暂停设计模式

目录 保护性暂停设计模式 获取结果 产生结果 总代码实现 测试 增加超时效果的Guarded suspension get(long timeout) 测试 保护性暂停设计模式 Guarded Suspension 即 保护性暂停; 是一种等待唤醒机制的一种规范 ,也可以理解为使用中设计模式,Java的API很多都按照保护性…

android中service实现原理分析

前言&#xff1a; 一开始的目标是解决各种各样的ANR问题的&#xff0c;我们知道&#xff0c;ANR总体上分有四种类型&#xff0c;这四种类型有三种是和四大组件相对应的&#xff0c;所以&#xff0c;如果想了解ANR发生的根因&#xff0c;对安卓四大组件的实现流程是必须要了解的…

第一个完整的CMake工程

第一个完整的CMake工程一、概述二、准备工作2.1 创建工程2.2 创建源码目录三、换个地方保存目标二进制文件3.1 add_subdirectory 指令说明3.2 重设目标二进制生成目录四、如何安装4.1 目标文件的安装4.2 普通文件的安装4.3 非目标文件的可执行程序安装(比如脚本之类)&#xff1…

【自学Java】Java选择结构if

Java选择结构if Java语言if条件判断 在 Java 中&#xff0c;关键字 if 是用于测试某个条件&#xff08;布尔型或逻辑型&#xff09;的语句是否满足一定的条件&#xff0c;如果满足特定的条件&#xff0c;则会执行 if 后面的大括号 {} 括起来的代码块&#xff0c;如果没有代码…

领导的本质就是:管理自己,影响别人

欲戴皇冠&#xff0c;必承其重。作为领导者&#xff0c;就应当承担相应的职责。管理好自己&#xff0c;下面还有很多双眼睛看着你&#xff0c;正人先正己&#xff0c;身正令才行&#xff0c;自己做好了&#xff0c;才可能影响到别人&#xff0c;成为一位受人尊重的领导者。 有…

一名普通Java程序员的2022的总结和2023的展望

前言今天是元旦节&#xff0c;也是2023年的第一天&#xff0c;首先祝各位亲朋好友们元旦快乐&#xff0c;在新的一年全家身体康健&#xff0c;诸事顺遂&#xff0c;阖家幸福&#xff0c;最重要的是身体健康&#xff0c;工作顺利&#xff0c;永无BUG永不加班&#xff01;&#x…

Eth08-EthCtrlConfig:以太网控制器的硬件操作的timeout值配置

文章目录 1 EthCtrlConfig:以太网控制器的硬件操作的timeout值配置传送门 ==>> AutoSAR入门和实战系列总目录 1 EthCtrlConfig:以太网控制器的硬件操作的timeout值配置 /MICROSAR/Eth_Enet/Eth/EthConfigSet/EthCtrlConfig: Configuration of the individual control…

国产操作系统

一次性安装所有的操作系统 首先安装vwworkstation 国产排名第一的deepin&#xff0c;华为鸿蒙&#xff0c; 国产操作系统都是基于linux mac系统 linux系统包括ubuntu,centos 最经典的win7,win10系统 全世界的操作系统加起来也就最多20种&#xff0c;掌握这几种操作系统&…