【STL】vector

目录

1. vector的使用

1.1 vector的定义

1.2 vector iterator 的使用

1.3 vector 空间增长问题

1.4 vector 增删查改

1.5 vector 迭代器失效问题(重点)

2.vector模拟实现


1. vector的使用

1.1 vector的定义

1.2 vector iterator 的使用

1.3 vector 空间增长问题

1. capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的。 这个问题经常会考察,不要固化的认为,vector增容都是2倍,具体增长多少是根据具体的需求定义 的。vs是PJ版本STL,g++是SGI版本STL。

2. reserve只负责开辟空间,如果确定知道需要用多少空间,reserve可以缓解vector增容的代价缺陷问 题。

3. resize在开空间的同时还会进行初始化,影响size。

1.4 vector 增删查改

1.5 vector 迭代器失效问题(重点)

        迭代器的主要作用就是让算法能够不用关心底层数据结构,其底层实际就是一个指针,或者是对指针进行了 封装,比如:vector的迭代器就是原生态指针T* 。因此迭代器失效,实际就是迭代器底层对应指针所指向的 空间被销毁了,而使用一块已经被释放的空间,造成的后果是程序崩溃(即如果继续使用已经失效的迭代器, 程序可能会崩溃)。

对于vector可能会导致其迭代器失效的操作有:

1. 会引起其底层空间改变的操作,都有可能是迭代器失效,比如:resize、reserve、insert、assign、 push_back等。

2. 指定位置元素的删除操作--erase

         erase删除pos位置元素后,pos位置之后的元素会往前搬移,没有导致底层空间的改变,理论上讲迭代 器不应该会失效,但是:如果pos刚好是最后一个元素,删完之后pos刚好是end的位置,而end位置是 没有元素的,那么pos就失效了。因此删除vector中任意位置上元素时,vs就认为该位置迭代器失效 了。

3. 注意:Linux下,g++编译器对迭代器失效的检测并不是非常严格,处理也没有vs下极端。

        SGI STL中,迭代器失效后,代码并不一定会崩溃,但是运行结果肯定不 对,如果it不在begin和end范围内,肯定会崩溃的。

4. 与vector类似,string在插入+扩容操作+erase之后,迭代器也会失效

迭代器失效解决办法:在使用前,对迭代器重新赋值即可。

2.vector模拟实现

#pragma once#include<assert.h>namespace erdong
{template<class T>class vector{public:typedef T* iterator;typedef const T* const_iterator;iterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin() const{return _start;}const_iterator end() const{return _finish;}// vector<int> v(10, 1);// // vector<int> v(10u, 1);// vector<string> v1(10, "1111");vector(size_t n, const T& val = T()){resize(n, val);}vector(int n, const T& val = T()){resize(n, val);}// [first, last)template<class InputIterator>vector(InputIterator first, InputIterator last){while (first != last){push_back(*first);++first;}}vector(){}vector(const vector<T>& v){_start = new T[v.capacity()];//memcpy(_start, v._start, sizeof(T)*v.size());for (size_t i = 0; i < v.size(); i++){_start[i] = v._start[i];}_finish = _start + v.size();_endofstorage = _start + v.capacity();}/*vector(const vector<T>& v):_start(nullptr), _finish(nullptr), _endofstorage(nullptr){reserve(v.capacity());for (auto e : v){push_back(e);}}*/void swap(vector<T>& v){std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_endofstorage, v._endofstorage);}// v1 = v2vector<T>& operator=(vector<T> v){swap(v);return *this;}~vector(){if (_start){delete[] _start;_start = _finish = _endofstorage = nullptr;}}// void reserve(size_t n){if (n > capacity()){size_t sz = size();T* tmp = new T[n];if (_start){//memcpy(tmp, _start, sizeof(T) * sz);for (size_t i = 0; i < sz; i++){tmp[i] = _start[i];}delete[] _start;}_start = tmp;_finish = _start + sz;_endofstorage = _start + n;}}// 10:35继续void resize(size_t n, const T& val = T()){if (n < size()){_finish = _start + n;}else{reserve(n);while (_finish != _start + n){*_finish = val;++_finish;}}}void push_back(const T& x){/*if (_finish == _endofstorage){size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;reserve(newcapacity);}*_finish = x;++_finish;*/insert(end(), x);}void pop_back(){erase(--end());}size_t capacity() const{return _endofstorage - _start;}size_t size() const{return _finish - _start;}T& operator[](size_t pos){assert(pos < size());return _start[pos];}const T& operator[](size_t pos) const{assert(pos < size());return _start[pos];}iterator insert(iterator pos, const T& x){assert(pos >= _start && pos <= _finish);if (_finish == _endofstorage){size_t len = pos - _start;size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;reserve(newcapacity);// 解决pos迭代器失效问题pos = _start + len;}iterator end = _finish - 1;while (end >= pos){*(end + 1) = *end;--end;}*pos = x;++_finish;return pos;}iterator erase(iterator pos){assert(pos >= _start && pos < _finish);iterator it = pos + 1;while (it != _finish){*(it - 1) = *it;++it;}--_finish;return pos;}private:iterator _start = nullptr;iterator _finish = nullptr;iterator _endofstorage = nullptr;};void print(const vector<int>& v){for (auto e : v){cout << e << " ";}cout << endl;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/813874.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java代码基础算法练习-自定义函数之求字符串长度-2024.04.13

任务描述&#xff1a; 写一函数&#xff0c;求一个字符串的长度&#xff08;字符串长度不超过255&#xff09;&#xff0c;然后在主函数中调用该函数 实现求长度操作。 任务要求&#xff1a; 代码示例&#xff1a; package April_2024;import java.util.Scanner;public class …

如何获取手机root权限?

获取手机的 root 权限通常是指在 Android 设备上获取超级用户权限&#xff0c;这样用户就可以访问和修改系统文件、安装定制的 ROM、管理应用权限等。然而&#xff0c;需要注意的是&#xff0c;获取 root 权限可能会导致手机失去保修、安全性降低以及使系统变得不稳定。在获取 …

电脑的日常使用 0 笔记本电脑验机使用体验帖

拯救者 Y7000P 2023 win11系统&#xff08;首发&#xffe5;6999&#xff09; 目录 开机前准备 开机后的验机工作 基本配置 一、 外观及使用体验 二、内部硬件使用体验 1.固态 3. CPU 4.显卡 总结 开机前准备 注意一定要全程录像 &#xff01; 检查快递外包装壳&#…

数据的未来:人工智能引领下的大数据革命

大数据是指在一定时间范围内&#xff0c;无法通过常规软件工具进行捕捉、管理和处理的数据集合&#xff0c;这种数据具有海量、高增长率和多样化的特点&#xff0c;需要采用新的处理模式才能发挥其更强的决策力、洞察发现力和流程优化能力。大数据将数据视为核心资源&#xff0…

Spring Boot | Spring Boot 整合 “Servlet三大组件“ ( Servlet / Filter / Listene )

目录: Spring Boot 整合 "Servlet三大组件" &#xff1a;1. 使用 "组件注册" 的方式 "整合Servlet三大组件" ( 实际操作为 : 创建自定义的"三大组件"对象 结合刚创建"的自定义组件对象"来 将 XxxRegistrationBean对象 通过…

PE文件的分析和构造超详细过程

本文详细讲述如何从0构造一个PE文件&#xff0c;运行该文件会弹出一个HelloPE的窗口 目录 预备知识 1. 构造DOS头IMAGE_DOS_HEADER 1.1 构造DOS_MZ头 1.2 构造DOS_STUB 2、构造PE头IMAGE_NT_HEADERS 248字节 2.1 signature 2.2 IMAGE_FILE_HEADER 2.3 IMAGE_OPTI…

在vue中配置样式 max-width:100px时,发现和width:100px一样没有对应的递增到最大宽度的效果?怎么回事?怎么解决?

原因&#xff1a; 可能时vue的样式大部分和display相关&#xff0c;有很多的联系&#xff0c;导致不生效 解决&#xff1a; 对设置max-width样式的元素设置display:inline-block;属性&#xff0c;即可生效&#xff0c;实现随着子元素的扩展而扩展并增加固定到最大的宽度

一些炫酷的按钮特效

一些炫酷的按钮特效 效果展示 完整vue版代码 <template><div class"test"><div><button class"custom-btn btn-1">btn-1</button><button class"custom-btn btn-2">btn-2</button><button class…

C语言—每日选择题—Day67

第一题 1、设有定义&#xff1a; char *p; &#xff0c;以下选项中不能正确将字符串赋值给字符型指针 p 的语句是&#xff08;&#xff09; 【多选】 A: pgetchar(); B: scanf("%s",p); C: char s[]"china"; ps; D: *p"china"; 答案与解析 A B D…

uniapp中实现中间大两边小轮播图

组件代码直接引入项目就可以看效果 <template><view class"certificate"><view class"title">{{title}}</view><view class"con-part2-con"><swiper class"swiper-tall" :autoplay"false"…

ISP图像处理pipeline简介1

ISP 是什么&#xff1f; ISP (Image Signal Processor)&#xff0c;图像信号处理器&#xff0c;是用于摄影和视频处理的一种专用芯片。它是用来干什么的呢&#xff1f;简单说就是用来将图像传感器&#xff08;CCD, CMOS&#xff09;信号转化成可视的信号的功能&#xff0c;这里…

CSS实现卡片在鼠标悬停时突出效果

在CSS中&#xff0c;实现卡片在鼠标悬停时突出&#xff0c;通常使用:hover伪类选择器。 :hover伪类选择器用于指定当鼠标指针悬停在某个元素上时&#xff0c;该元素的状态变化。通过:hover选择器&#xff0c;你可以定义鼠标悬停在元素上时元素的样式&#xff0c;比如改变颜色、…

java mysql 示例

java mysql 示例 一、登陆mysql&#xff1b;创建账号允许远程访问 -- 创建用户 CREATE USER user% IDENTIFIED BY password; -- 授予远程访问权限 GRANT ALL PRIVILEGES ON *.* TO user% WITH GRANT OPTION;二、关闭防火墙 sudo ufw disable三、下载jar包&#xff0c;并解压…

简单工厂模式大解析:让代码创造更高效、更智能!

个人主页: danci_ &#x1f525;系列专栏&#xff1a;《设计模式》《MYSQL应用》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;坚持默默的做事。 &#x1f680; 转载自热榜文章&#xff1a;探索设计模式的魅力&#xff1a;简单工厂模式 简单工厂模式&#x…

Github学生认真全流程指南!避坑!保姆级教程!

重回学生身份,当然要好好享受一番学生权益了,而学生邮箱就是最好的资源与服务。 关于Github学生包(GitHub Student Developer Pack) Github的学生包里包括Github Pro账户,这是一个高级的 GitHub 账户类型,提供更多功能和服务,如私有仓库、团队协作工具等。以及Github …

CH254X 8051芯片手册介绍

1 8051CPU 8051是一种8位元的单芯片微控制器&#xff0c;属于MCS-51单芯片的一种&#xff0c;由英特尔(Intel)公司于1981年制造。Intel公司将MCS51的核心技术授权给了很多其它公司&#xff0c;所以有很多公司在做以8051为核心的单片机&#xff0c;如Atmel、飞利浦、深联华等公…

编辑距离问题

编辑距离 时间限制&#xff1a;1秒 内存限制&#xff1a;128M 题目描述 设A和B是两个字符串。我们要用最少的字符操作次数&#xff0c;将字符串A转换为字符串B。这里所说的字符操作共有三种&#xff1a; 1、删除一个字符&#xff1b; 2、插入一个字符&#xff1b…

Docker 学习笔记(八):Dockerfile实战篇,制作 Tomcat 镜像,发布镜像到 DockerHub 和阿里云

一、前言 记录时间 [2024-4-13] 系列文章简摘&#xff1a; Docker 学习笔记&#xff08;六&#xff09;&#xff1a;挑战容器数据卷技术一文通&#xff0c;实战多个 MySQL 数据同步&#xff0c;能懂会用&#xff0c;初学必备 Docker 学习笔记&#xff08;七&#xff09;&#x…

(三)ffmpeg 解码流程以及函数介绍

一、视频解码流程 二、函数介绍 1.avformat_network_init 函数作用&#xff1a; 执行网络库的全局初始化。这是可选的&#xff0c;不再推荐。 此函数仅用于解决旧GnuTLS或OpenSSL库的线程安全问题。如果libavformat链接到这些库的较新版本&#xff0c;或者不使用它们&#…

hive窗口分析函数使用详解系列二之分组排序窗口函数

1.综述 我们讨论面试中各大厂的SQL算法面试题&#xff0c;往往核心考点就在于窗口函数&#xff0c;所以掌握好了窗口函数&#xff0c;面对SQL算法面试往往事半功倍。 已更新第一类聚合函数类&#xff0c;点击这里阅读 hive窗口函数聚合函数类 本节介绍Hive聚合函数中的第二类…