当前位置: 首页 > news >正文

vector 的扩容机制

vector 的扩容机制是指当现有容量不足以容纳新元素时,自动分配更大的内存空间、复制旧元素到新空间,并释放旧空间的过程。其核心逻辑是 **“以空间换时间”**,通过预留额外容量减少频繁扩容的开销。

一、关键概念

在理解扩容机制前,先明确 vector 的两个核心属性:

  • size:当前已存储的元素数量。
  • capacity:当前分配的内存可容纳的最大元素数量(capacity >= size)。

当 size == capacity 时,再插入元素就会触发扩容。

二、扩容的完整流程

  1. 判断是否需要扩容

当执行 push_back、insert 等插入操作时,若 size + 新增元素数 > capacity,则触发扩容。

  1. 计算新容量

不同编译器(如 GCC、MSVC)的扩容策略略有差异,通常是 “当前容量的 1.5 倍或 2 倍”

    • GCC:新容量 = 旧容量 × 1.5(整数除法,如旧容量 5 → 新容量 7)。
    • MSVC:新容量 = 旧容量 × 2(如旧容量 5 → 新容量 10)。
    • 若初始容量为 0(空 vector),首次扩容通常直接分配能容纳 1 个元素的空间,后续按倍数增长。
  1. 分配新内存

根据新容量在堆上分配一块更大的连续内存(类型为元素类型的数组)。

  1. 复制 / 移动旧元素

将旧内存中的元素逐个复制(或移动,C++11 后)到新内存中。

  1. 释放旧内存

销毁旧内存中的元素,释放旧内存空间。

  1. 更新内部指针

将 vector 内部指向数据的指针(如 _M_start、_M_end、_M_capacity)指向新内存,并更新 size 和 capacity。

三、代码示例与验证

通过示例观察 vector 的 size、capacity 变化,验证扩容机制:

#include <iostream>

#include <vector>

int main() {

std::vector<int> v;

// 初始状态:size=0,capacity=0

std::cout << "初始: size=" << v.size() << ", capacity=" << v.capacity() << std::endl;

// 插入元素,观察扩容

for (int i = 0; i < 10; ++i) {

v.push_back(i);

std::cout << "插入" << i << ": size=" << v.size()

<< ", capacity=" << v.capacity() << std::endl;

}

return 0;

}

GCC 环境下的输出(1.5 倍扩容):

初始: size=0, capacity=0

插入0: size=1, capacity=1 // 首次扩容到1

插入1: size=2, capacity=2 // 1×2=2(因1.5取整后仍为1,故直接扩到2)

插入2: size=3, capacity=3 // 2×1.5=3

插入3: size=4, capacity=4 // 3×1.5=4.5→取整4

插入4: size=5, capacity=6 // 4×1.5=6

插入5: size=6, capacity=6

插入6: size=7, capacity=9 // 6×1.5=9

插入7: size=8, capacity=9

插入8: size=9, capacity=9

插入9: size=10, capacity=13 // 9×1.5=13.5→取整13

MSVC 环境下的输出(2 倍扩容):

初始: size=0, capacity=0

插入0: size=1, capacity=1 // 首次扩容到1

插入1: size=2, capacity=2 // 1×2=2

插入2: size=3, capacity=4 // 2×2=4

插入3: size=4, capacity=4

插入4: size=5, capacity=8 // 4×2=8

插入5: size=6, capacity=8

插入6: size=7, capacity=8

插入7: size=8, capacity=8

插入8: size=9, capacity=16 // 8×2=16

插入9: size=10, capacity=16

四、扩容的影响与优化

  1. 性能开销

扩容涉及内存分配、元素复制和旧内存释放,频繁扩容会导致性能下降(尤其是元素为大型对象时,复制成本高)。

  1. 迭代器失效

扩容后,旧内存被释放,指向旧内存的迭代器、指针、引用都会失效(需重新获取)。

  1. 优化策略
    • 提前调用 reserve(n):手动预留足够容量(capacity 直接扩到 n),避免多次自动扩容。

例:v.reserve(10); 可让上述示例中 capacity 直接从 0 变为 10,插入 10 个元素时不再扩容。

    • 避免存储大量大型对象:可存储指针(或智能指针),减少复制成本。

总结

vector 的扩容机制是 **“当容量不足时,按当前容量的 1.5 倍或 2 倍分配新内存,复制旧元素后释放旧内存”**,其设计平衡了内存利用率和操作效率。实际使用中,可通过 reserve 提前预留容量优化性能。

http://www.dtcms.com/a/549242.html

相关文章:

  • part1~2 神经网络基础
  • SQL注入过滤绕过fuzz字典
  • CH32 WCH-LINK -Error: Failed to Open WCH-Link.
  • 构建AI智能体:七十九、从SVD的理论到LoRA的实践:大模型低秩微调的内在逻辑
  • Blackwell GPU提供LLVM和MLIR支持的相关工作 报告
  • 宁波网站开发建设网上做娱乐广告的网站
  • 浙江制造品牌建设网站做微信网站公司名称
  • Babylon.js中ArcRotateCamera.interpolateTo 方法使用备忘
  • 【OD刷题笔记】- CPU算力分配
  • iOS 抓包工具有哪些,开发者的选型与实战指南
  • 测试过程涉及python自动化及其他相关面试问题汇总
  • 免费网站建设讯息全站加速 wordpress
  • 哪里网站建设公司比较好网站建设销售工作职责
  • 推荐一款免费的语音识别网站,上传音频即可
  • 笔记C++语言,太焦虑了
  • 分公司一般做网站吗音乐网站建设目标
  • Java 21 虚拟线程 vs 缓存线程池与固定线程池
  • 在线开发培训网站建设小型餐饮店面设计
  • ZYNQ USB按键读写操作详解:从裸机到Linux系统的完整实现
  • 如何在Windows桌面实现自由悬浮计时?
  • BEV环视感知算法从环境部署开始
  • 看上去高端的网站深圳培训学校
  • 狂飙与重构:机器人IPO浪潮背后的系统焦虑与感知进化
  • 21.静态NAT
  • 做头像的网站wordpress拖拽式
  • 【C++】位运算算法习题
  • 券商上云,不止AI和大数据,还有USB Server
  • 软件设计师知识点总结:面向对象技术(设计模式)
  • 广西建设局建设行政主管部网站企业app开发企业
  • Python 实战:Web 漏洞 Python POC 代码及原理详解(3)