【C++第11章】Vector

news2024/11/26 16:37:09

【C++第11章】Vector

vector介绍🧐

  vector是表示可变大小数组的序列容器,它类似于数组,但大小可以动态改变,并且大小会被容器自动处理。本质上说,vector使用动态分配数组来存储元素,为了减少扩容代价,vector会分配额外空间进行元素存储。

  对比其他动态序列容器,vector访问元素时更加高效,尾插和尾删相对更容易,可以将其看为一个顺序表进行理解。

vector基本使用🧐

初始化和遍历🔎

  由于C++封装的特性,所以vector与string的使用相似,首先来看初始化和遍历:

```c++
	vector<int> v(10,0);

	vector<int> v2(10, 99);

	vector<int> arr = { 100,9,10,8,6,5,4,3,2,1 }; //数组初始化

	vector<int> v3(v2.begin(), v2.end());

	string s("hello world");

	vector<int> v4(s.begin(), s.end());

	for (size_t i = 0; i < v2.size(); i++) //下标遍历
	{
		cout << v2[i] << " ";
	}
	cout << endl;

	vector<int>::iterator it = v4.begin(); //迭代器遍历
	while (v4.end() != it)
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;

	for (auto s : v) //范围for
	{
		cout << s << " ";
	}
```

Pasted image 20240727095533

扩容🔎

  在vs下扩容约1.5倍,g++下为2倍

Pasted image 20240727095601

vector常用函数🧐

reserve和resize🔎

  reserve不会对开出的空间初始化,所以仅capacity变动,size还是原来的,如果我们强行访问就会触发下标断言。

  resize可以自动初始化,且size会跟随数据量进行变动。

Pasted image 20240727100516

shrink_to_fit🔎

  当size小于capacity时,shrink可以进行缩容,但一般是异地缩容,是用时间来换空间,要小心使用。

Pasted image 20240727100855

insert、erase、front和back🔎

void test_vector4()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	cout << v.front() << endl; //取头
	v.insert(v.begin(), 100); //头插100
	cout << v.front() << endl;
	cout << v.back() << endl; //取尾
	v.erase(v.begin()); //头删 
	for (auto s : v)
	{
		cout << s << " ";
	}
}

Pasted image 20240727102058

find🔎

  vector没有自己的find函数,但STL库中有find,而string由于要找字符串,STL的find不能满足需求,所以string有自己的find。

Pasted image 20240727102327

clear🔎

  clear一般情况不清理capacity,不过可以配合shrink将capacity也清理掉

Pasted image 20240727102759

流插入流提取🧐

  vector不提供流插入和流提取,因为编译器不知道你要以什么形式打印出来,并且已有的函数足够使用,所以流插入和流提取没有必要

image-20240731200745690

迭代器失效🧐

  迭代器失效是指对容器的操作影响了元素的存放位置,导致迭代器指向的空间被销毁,而使用一块已经被释放的空间,造成的后果是程序崩溃

  如下代码,当我们使用erase删除偶数时,碰到连续的偶数或者末尾是偶数就会出现问题。

void test_vector1()
{
	vector<int> v;
	v.push_back(2); //连续的偶数删除不完整
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
    //v.push_back(6); //末尾为偶数会直接报错
	auto it = v.begin();
	while (it != v.end())
	{
		if (*it % 2 == 0)
		{
			v.erase(it);
		}
		++it;
	}
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
}

Pasted image 20240729225332

Pasted image 20240729225228

  原因在于,当我们erase完数据后,数据会挪动位置,而迭代器也跟着挪动,此时如果下一位是奇数那恰好不删除,如果是偶数就会跳过数据

动画

  当末尾为偶数时,erase后迭代器还是会继续往后走,it超过了end,此时已经是非法访问了,++it将会使程序崩溃。

动画1

  并且在insert后由于扩容会删除旧空间,而迭代器还指向原空间,也会出现迭代器失效。所以我们默认为会引起其底层空间改变的操作,都有可能使迭代器失效,在vs19下STL会强制检查,进行扩容删除操作后再使用迭代器会报错,g++下不会强制检查。

  解决方式很简单,erase和insert都给了返回值,我们只需要用迭代器接收新的地址即可。

Pasted image 20240729231123

memcpy的拷贝问题🧐

  在模拟底层实现时发现,写扩容用memcpy会出现一个奇怪的问题,当我们使用vector存string类型时,前四次尾插都正常。

Pasted image 20240729231652

  但是到了第五次,vector扩容,此时打印出错了。

Pasted image 20240729231740

  在了解后发现,memcpy是内存的二进制格式拷贝,将一段空间内容原封不动拷贝到另一段内存空间中,如果是内置类型,memcpy可以高效正确的拷贝,但自定义类型使用memcpy,且涉及空间时就会出错,因为memcpy实际是浅拷贝,memcpy会把_str的指针指向旧空间,当我们delete旧空间后,析构导致_str变成随机值,所以打印出错。

image-20240802191357383

  使用for循环一个一个赋值就可以解决了。

Pasted image 20240729235733

结尾👍

以上便是vector的全部介绍,如果有疑问或者建议都可以私信笔者交流,大家互相学习,互相进步!🌹

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

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

相关文章

音频剪辑软件哪个好用?音乐制作必备的6款音频剪辑工具

在这个充满声音的世界里&#xff0c;音乐和音频不仅仅是艺术表达的一种形式&#xff0c;更是情感的载体&#xff0c;是故事的讲述者。 你是否曾想过&#xff0c;那些令人动容的电影配乐、让人热血沸腾的电音节拍或是清晨唤醒你的温柔闹钟&#xff0c;是如何从一堆杂乱无章的声…

坐牢第二十三天 20240806(IO)

一.作业 1> 使用消息队列完成两个进程之间相互通信 A.c #include <myhead.h> // 要发送的消息类型 struct msgbuf {long mtype; /* message type, must be > 0 */char mtext[1024]; /* message data */ }; #define SIZE sizeof(struct msgbuf) - sizeof(l…

PEPM系统Cookie请求头远程代码执行漏洞复现 [附POC]

文章目录 PEPM系统Cookie请求头远程代码执行漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现PEPM系统Cookie请求头远程代码执行漏洞复现 [附POC] 0x01 前言 免责声明:请勿利用文章内的相关技术从事非法测试,…

mem0ai+ollama+qwen2搭建中文版运行环境

准备模型 支持function的qwen2模型 随便找了一个&#xff0c;也可以下载其他支持function的模型&#xff0c;或者自己下载模型文件搭建 ollama run sam4096/qwen2toolsembedder 模型 ollama run nomic-embed-text拉取mem0ai 源码&#xff0c;切换对应分支 git clone https…

【Foundation】(三)transformers之Model

文章目录 1、介绍1.1、 模型类型1.2、Model Head 2、模型加载3、模型调用3.1、不带Model Head的模型调用3.2、带Model Head的模型调用 4、模型微调实战4.1、导包4.2、加载数据4.3、创建数据集4.4、划分数据集4.5、创建加载器4.6、创建模型以及优化器4.7、模型训练4.8、模型评估…

Figma 替代品 Excalidraw 安装和使用教程

如今远程办公盛行&#xff0c;一个好用的在线白板工具对于团队协作至关重要。然而&#xff0c;市面上的大多数白板应用要么功能单一&#xff0c;要么操作复杂&#xff0c;难以满足用户的多样化需求。尤其是在进行头脑风暴、流程设计或产品原型绘制时&#xff0c;我们常常会遇到…

linux入门到精通-第二十章-bufferevent(开源高性能事件通知库)

目录 参考bufferevent简单介绍工作流程事件Api新建事件节点 bufferevent_socket_new设置事件节点回调bufferevent_setcb使事件势能bufferevent_enable发送数据bufferevent_write接收数据bufferevent_read evconnlistener的简介 参考 视频教程 libevent的基本使用 libevent–bu…

HslCommunicationDemo各品牌Plc通信测试软件工具

目录 1、HslCommunicationDemo程序包 2、ModbusTCP举例说明 (0)概述 &#xff08;1&#xff09;线圈写操作 &#xff08;2&#xff09;寄存器写操作 3、C#工程中DLL库文件使用 &#xff08;1&#xff09;创建Winform程序工程 &#xff08;2&#xff09;写寄存器 1、HslC…

【Linux】匿名管道|命名管道|pipe|mkfifo|管道原理|通信分类|管道的特征和情况

目录 ​编辑 进程间通信 为什么要有进程间通信 进程通信的目的 进程间通信分类 如何理解通信 管道 匿名管道 管道原理 半双工 通信两问 pipe 演示 管道情况 管道的特征 命名管道 mkfifo指令 mkfifo接口 命名管道提供的是流式服务 匿名管道与命名管道的…

day08 1.进程间通信

work1.c #include <myhead.h> //要发送的消息类型 struct msgbuf {long mtype;char mtext[1024]; };#define SIZE sizeof(struct msgbuf)-sizeof(long)int main(int argc, const char *argv[]) {pid_t pid fork();if(pid -1){perror("fork error");return -…

Webpack入门基础知识及案例

webpack相信大家都已经不陌生了&#xff0c;应用程序的静态模块打包工具。前面我们总结了vue&#xff0c;react入门基础知识&#xff0c;也分别做了vue3的实战小案例&#xff0c;react的实战案例&#xff0c;那么我们如何使用webpack对项目进行模块化打包呢&#xff1f; 话不多…

RPA与智慧政务的关系

自1992年国务院明确提出构建全国行政机关办公决策系统&#xff0c;我国政府信息化建设已走过三十余年历程&#xff0c;并取得了阶段性成果&#xff0c;随着社会需求的变化以及信息技术和数字化工具的不断完善&#xff0c;人们对政府的信息化建设也提出了新的要求&#xff0c;推…

【C#语音文字互转】C#语音转文字(方法一)

Whisper.NET开源项目&#xff1a;https://github.com/sandrohanea/whisper.net/tree/main 一. 环境准备 在VS中安装 Whisper.net&#xff0c;在NuGet包管理器控制台中运行以下命令&#xff1a; Install-Package Whisper.net Install-Package Whisper.net.Runtime其中运行时包…

uniapp 实现自定义缩略滚动条

<template><view class"container-scroll"><!-- 文字导航 --><scroll-view class"scroll-view-text" scroll-x"true" v-if"type 1"><navigator:url"item.url"class"scroll-view-item"…

LE-50821F/FA激光扫描传感器|360°避障雷达之功能与连接使用说明

LE-50821F/FA激光扫描传感器|360避障雷达广泛应用于工业自动化、移动机器人应用场景中的环境感知、高精度定位&#xff08;如建图、扫描、避障、防护等&#xff09; LE-50xxxF系列升级扫描频率最高可达600KHz​​​​。 本文重点介绍LE-50821F/FA激光扫描传感器|360避障雷达之…

【C++】二维数组 数组名

二维数组名用途 1、查看所占内存空间 2、查看二维数组首地址 针对第一种用途&#xff0c;还可以计算数组有多少行、多少列、多少元素 针对第二种用途&#xff0c;数组元素、行数、列数都是连续的&#xff0c;且相差地址是有规律的 下面是一个实例 #include<iostream&g…

FreeRTOS基础入门——FreeRTOS的系统配置(三)

个人名片&#xff1a; ​ &#x1f393;作者简介&#xff1a;嵌入式领域优质创作者&#x1f310;个人主页&#xff1a;妄北y &#x1f4de;个人QQ&#xff1a;2061314755 &#x1f48c;个人邮箱&#xff1a;[mailto:2061314755qq.com] &#x1f4f1;个人微信&#xff1a;Vir202…

基于大模型的Agent

2023年&#xff0c;对于所有的人工智能领域只有一个共同的主题——大模型。大模型的受关注程度与发展速度可谓前所未有。其中&#xff0c;基于大模型的Agent又是最近几个月大模型领域的热点。这不开始研究没有几个月&#xff0c;综述文章都出来了&#xff0c;你说快不快&#x…

FashionAI比赛-服饰属性标签识别比赛赛后总结(来自 Top14 Team)

关联比赛: FashionAI全球挑战赛—服饰属性标签识别 推荐大家看本篇博客之前&#xff0c;看一下数据集制作的方法&#xff0c;如何做一个实用的图像数据集 PS&#xff1a;我是参加完比赛之后才看的&#xff0c;看完之后&#xff0c;万马奔腾.....&#xff0c;因为发现比赛中还…

62 函数参数——传递参数时的序列解包

与可变长度的参数相反&#xff0c;这里的序列解包是指实参&#xff0c;同样也有 * 和 ** 两种形式。 ① 调用含有多个位置参数的函数时&#xff0c;可以使用 Python 列表、元组、集合、字典以及其他可迭代对象作为实参&#xff0c;并在实参名称前加一个星号&#xff0c;Python …