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

全网最细vector精讲:从接口使用到迭代器失效、模拟实现,C++面试必看

全网最细vector精讲:从接口使用到迭代器失效、模拟实现,C++面试必看

本文专注STL核心vector,覆盖面试高频考点、工程避坑、可直接运行代码,适合面试突击、期末复习、刷题提速

文章目录

  • 全网最细vector精讲:从接口使用到迭代器失效、模拟实现,C++面试必看
    • 一、开篇:vector 到底有多重要?
    • 二、vector 核心使用(高频接口一网打尽)
      • 1. 四种构造方式
      • 2. 迭代器(遍历通用写法)
      • 3. 容量操作(面试必考)
      • 4. 增删查改
    • 三、vector 扩容机制(面试高频)
      • 1. 扩容倍数
      • 2. 扩容代价
      • 3. 优化:提前 reserve
    • 四、vector 迭代器失效(最坑、最易错)
      • 1. 什么是迭代器失效?
      • 2. 两类失效场景
        • (1)扩容导致失效(空间被释放)
        • (2)erase 导致失效(元素前移)
      • 3. 平台差异
    • 五、vector 模拟实现(面试手写)
      • 1. 核心结构
      • 2. reserve 实现(重点:避开 memcpy 坑)
      • 3. push_back 实现
      • 4. erase 实现(处理迭代器失效)
    • 六、vector 高频面试题总结
    • 七、总结(一分钟背完)

一、开篇:vector 到底有多重要?

vector 是C++ STL 最常用、最基础的动态数组,底层是连续内存,支持随机访问,自动扩容。

  • 刷题:90% 数组题用 vector
  • 工程:替代原生数组,安全、易用
  • 面试:扩容机制、迭代器失效、模拟实现 必问

它完美解决原生数组定长、越界、管理麻烦的问题,是 C++ 开发者必备技能。


二、vector 核心使用(高频接口一网打尽)

1. 四种构造方式

#include<iostream>#include<vector>usingnamespacestd;voidTestVector(){// 1. 无参构造vector<int>v1;// 2. 构造n个valvector<int>v2(5,10);// 3. 拷贝构造vector<int>v3(v2);// 4. 迭代器区间构造intarr[]={1,2,3,4,5};vector<int>v4(arr,arr+5);}

2. 迭代器(遍历通用写法)

vector 迭代器本质就是原生指针 T*,高效、轻量。

voidTestIterator(){vector<int>v={1,2,3,4,5};// 正向迭代器vector<int>::iterator it=v.begin();while(it!=v.end()){cout<<*it<<" ";++it;}cout<<endl;// 范围for(底层替换为迭代器)for(autoe:v)cout<<e<<" ";}

3. 容量操作(面试必考)

接口作用区别
size()获取有效元素个数实际用了多少
capacity()获取容量最多能存多少
resize(n)改变 size,开空间+初始化影响有效数据
reserve(n)改变 capacity,只开空间不影响有效数据
voidTestCapacity(){vector<int>v;v.reserve(100);// 提前开空间,避免频繁扩容v.resize(10,1);// 10个1}

4. 增删查改

voidTestModify(){vector<int>v;// 尾插尾删v.push_back(1);v.push_back(2);v.pop_back();// operator[] 随机访问(最常用)cout<<v[0]<<endl;// insert / erasev.insert(v.begin(),0);v.erase(v.begin());}

三、vector 扩容机制(面试高频)

1. 扩容倍数

  • VS(PJ 版 STL):1.5 倍扩容
  • G++(SGI 版 STL):2 倍扩容

2. 扩容代价

扩容不是原地追加,而是:
开辟新空间 → 拷贝元素 → 释放旧空间
频繁扩容 = 频繁拷贝 = 效率暴跌。

3. 优化:提前 reserve

voidTestExpandOpt(){vector<int>v;v.reserve(100);// 一次开好,无扩容for(inti=0;i<100;++i)v.push_back(i);}

四、vector 迭代器失效(最坑、最易错)

1. 什么是迭代器失效?

vector 迭代器 = 原生指针。
底层空间被释放 / 元素被移动 → 指针变野指针 → 失效

2. 两类失效场景

(1)扩容导致失效(空间被释放)

push_back / insert / resize / reserve / assign都可能触发。

// 错误示例vector<int>v={1,2,3,4,5};autoit=v.begin();v.reserve(100);// 扩容,旧空间释放// cout << *it << endl; // 崩溃!it已失效
(2)erase 导致失效(元素前移)

erase 会让迭代器直接失效,不能直接 ++it。

// 错误写法:删除偶数必崩vector<int>v={1,2,3,4};autoit=v.begin();while(it!=v.end()){if(*it%2==0)v.erase(it);++it;// 失效后++,未定义行为}// 正确写法:接收erase返回值while(it!=v.end()){if(*it%2==0)it=v.erase(it);// 更新迭代器else++it;}

3. 平台差异

  • VS:检查严格,失效直接崩溃
  • Linux g++:检查宽松,不崩但结果错误
    统一原则:只要扩容/erase,迭代器必须重新获取

五、vector 模拟实现(面试手写)

1. 核心结构

底层用三个指针管理:

  • _start:数据起始
  • _finish:有效数据结尾
  • _endOfStorage:容量结尾
namespacebite{template<classT>classvector{public:typedefT*iterator;vector():_start(nullptr),_finish(nullptr),_endOfStorage(nullptr){}~vector(){delete[]_start;_start=_finish=_endOfStorage=nullptr;}iteratorbegin(){return_start;}iteratorend(){return_finish;}size_tsize(){return_finish-_start;}size_tcapacity(){return_endOfStorage-_start;}T&operator[](sslocal://flow/file_open?url=size_t+pos&flow_extra=eyJsaW5rX3R5cGUiOiJjb2RlX2ludGVycHJldGVyIn0=){return_start[pos];}private:iterator _start;iterator _finish;iterator _endOfStorage;};}

2. reserve 实现(重点:避开 memcpy 坑)

memcpy 是浅拷贝,存放 string/vector 等对象时会重复释放、崩溃
必须用循环深拷贝

voidreserve(size_t n){if(n>capacity()){size_t oldSize=size();T*tmp=newT[n];// 不能用memcpy!for(size_t i=0;i<oldSize;++i)tmp[i]=_start[i];delete[]_start;_start=tmp;_finish=_start+oldSize;_endOfStorage=_start+n;}}

3. push_back 实现

voidpush_back(constT&val){if(_finish==_endOfStorage){size_t newCapacity=capacity()==0?4:capacity()*2;reserve(newCapacity);}*_finish=val;++_finish;}

4. erase 实现(处理迭代器失效)

iteratorerase(iterator pos){// 向后挪动覆盖for(iterator it=pos;it<end()-1;++it)*it=*(it+1);--_finish;returnpos;// 返回下一个有效迭代器}

六、vector 高频面试题总结

  1. vector 扩容倍数?
    VS 1.5 倍,Linux 2 倍。
  2. resize 和 reserve 区别?
    resize 改 size 并初始化;reserve 只改容量。
  3. 迭代器失效原因?
    扩容释放空间、erase 移动元素。
  4. 为什么不能用 memcpy 拷贝 vector 元素?
    浅拷贝,对象带资源会双重释放、内存泄漏。
  5. vector 与 list 区别?
    vector 连续内存、随机访问快;list 链表、任意位置增删快。

七、总结(一分钟背完)

  1. vector 是连续内存动态数组,支持随机访问,迭代器=原生指针。
  2. 扩容:VS 1.5 倍、G++ 2 倍,用reserve提前优化。
  3. 迭代器失效是最大坑:扩容/erase 后必须重新获取。
  4. 模拟实现核心:三指针 + 深拷贝,禁止 memcpy
  5. 刷题首选 vector,工程替代数组,安全高效。

http://www.jsqmd.com/news/606799/

相关文章:

  • 别再只盯着频率了!手把手教你从功耗和架构层面优化DDR控制器设计
  • 从安装到实战:OpenClaw+Qwen3-4B完成跨境电商数据抓取
  • 从命令行恐惧到图形化掌控:一位系统管理员的Hyper-V设备直通之旅
  • RTX5060 Ti显卡安装cuda版本PyTorch记录
  • 大模型应用落地深度实践:Training Recipe、Omni与Agent技术栈全解析
  • 当作物生长模型遇上基因组选择:1+1 2 的育种新范式
  • 御坂翻译器:突破语言壁垒的Galgame实时翻译解决方案
  • 伏羲模型:人工智能技术在中期天气预报领域的革命性应用
  • 如何在macOS上解锁QQ音乐加密文件:QMCDecode完全指南
  • 避坑指南:EXT151(QRC)安装中那个‘OA库不存在’的报错,我是这样解决的
  • 【Matlab】MATLAB教程:ode15s求解刚性方程(含化工/控制仿真应用)
  • 深求·墨鉴场景应用:古籍数字化原来可以这么简单优雅
  • 最新且精准的响应:RAG相比静态训练数据的优势
  • 避开这3个坑,你的线结构光标定精度立马提升:从图像采集到参数验证全流程避雷指南
  • 随笔——视觉惯性SLAM方法比较
  • 3分钟搞定!Calibre豆瓣插件安装全攻略,轻松获取中文图书元数据
  • 本科生也能冲:大模型实习准备指南
  • 如何在Windows上实现MacBook级别的三指拖拽体验:ThreeFingerDragOnWindows完整指南
  • 大模型开发入门:三大项目带你快速上手AI应用开发
  • CSS如何通过Sass实现投影阴影封装_通过函数动态调节阴影深度
  • 重启不用输 PIN!Android 17 终于把 SIM 卡安全做明白了
  • 如何实现AI到PSD的无损转换?告别矢量信息丢失的终极方案
  • 第十七节:数据库直连技能——SQL查询与数据分析
  • 3步突破艾尔登法环帧率限制:专业玩家的性能优化指南
  • EasyESPConnect:基于NVS的轻量级ESP32 WiFi配置库
  • 【Matlab】MATLAB教程:微分方程参数估计(含拟合案例与系统参数辨识应用)
  • 320x240 TFT屏的SPI DMA驱动避坑指南:基于HC32F460的时序调试心得
  • OpenClaw跨平台控制:Qwen3.5-9B管理多台设备
  • MPI并行编程避坑指南:实现Cannon算法时,你的进程通信真的高效吗?
  • 你的云服务器在偷偷挖矿吗?手把手教你用top命令和阿里云安全中心揪出‘矿工’