C++的vector

news2024/11/15 23:27:08

文章目录

  • 迭代器失效问题
  • 构造函数
  • 赋值运算符
  • begin() + end()
  • size() + capacity() + empty()
  • reserve()
  • operator[ ]
  • insert()
  • erase()
  • resize()

迭代器失效问题

迭代器失效,实际就是迭代器底层对应指针所指向的空间被销毁了,而使用一块已经被释放的空间
1.扩容导致迭代器失效问题
在对容器进行insert、resize、reserve、assign、push_back等操作时会导致_capacity发生变化,在容量发生变化时,可能会出现异地扩容,这就会导致原来的迭代器指向已经被释放的空间,从而导致程序崩溃。
2.指定位置元素的删除操作----erase

#include <iostream>
#include <vector>
using namespace std;

int main()
{
	int ar[] = { 1,2,3,4,0,5,6,7,8,9 };
	int n = sizeof(ar) / sizeof(int);
	vector<int> v(ar, ar + n);
	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
		if (*it != 0)
			cout << *it;
		else
			v.erase(it);
		it++;
	}
	return 0;
}

以上述程序为例,如果是在VS中只要是在删除操作后,迭代器就会失效,如果不给迭代器重新赋值,直接再次使用迭代器就会强制报错,而在Linux中不一定会报错,因为可能会误打误撞的让程序可以运行,结果也会正确
上述程序理论上可以正常运行,但是在VS中规定只要是在erase之后再次直接使用迭代器就会强制报错

构造函数

在这里插入图片描述
无参构造

vector()
	:_start(nullptr)
	,_finish(nullptr)
	,_end_of_storage(nullptr)
{

}

拷贝构造

//拷贝构造
//因为浅拷贝会导致析构时被析构两次,所以我们要写一个深拷贝
vector(const vector<T>& v)
	:_start(nullptr)
	,_finish(nullptr)
	,_end_of_storage(nullptr)
{
	_start = new T[v.capacity()];
	memcpy(_start, v._start, sizeof(T) * v.size());
	_finish = _start + v.size();
	_end_of_storage = _start + v.capacity();
}

使用迭代器进行初始化构造

template<class InputIterator>
vector(InputIterator first, InputIterator last)
{
	while (first != last)
	{
		push_back(*first);
		++first;
	}
}

赋值运算符

在这里插入图片描述

void swap(vector<T>& v)
{
	std::swap(_start, v._start);
	std::swap(_finish, v._finish);
	std::swap(_end_of_storage, v._end_of_storage);
}

//赋值运算符重载
//vector<T>& operator=(vector<T>& v)
vector<T>& operator=(vector<T> v)//参数v要是拷贝的,传引用的话就是原对象,赋值后这里会导致原对象被改变
{
	swap(v);
	return *this;
}

begin() + end()

在这里插入图片描述
在这里插入图片描述

iterator begin()
{
	return _start;
}

iterator end()
{
	return _finish;
}

const_iterator begin() const
{
	return _start;
}

const_iterator end() const
{
	return _finish;
}

size() + capacity() + empty()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

size_t size() const
{
	return _finish - _start;
}

size_t capacity() const
{
	return _end_of_storage - _start;
}

bool empty() const
{
	return _end_of_storage == _start;
}

reserve()

在这里插入图片描述

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);
			delete[] _start;
		}
		_start = tmp;
		//_finish = _start + size();//size的计算会出错,因为此时的_start的指向已经发生改变,_finsh还是指向原来的位置
		_finish = _start + sz;
		_end_of_storage = _start + n;
	}
}

operator[ ]

在这里插入图片描述

T& operator[](size_t pos)
{
	assert(pos < size());
	return _start[pos];
}

const T& operator[](size_t pos) const
{
	assert(pos < _finish - _start);
	return _start + pos;
}

insert()

在这里插入图片描述

//insert以后迭代器可能会失效(扩容)
//insert以后就不要使用这个迭代器了,因为他可能失效了
void insert(iterator pos, const T& x)//位置传指针就会避免在0位置插入导致的整型提升问题,因为地址不会小于0
{
	assert(pos >= _start && pos <= _finish);
	if (_finish == _end_of_storage)
	{
		//注意迭代器失效问题
		//因为一旦扩容,就会导致pos指向的位置还是原来的位置,而扩容后_start指向了新空间
		size_t len = pos - begin();//1保存pos相对位置
		size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;
		reserve(newcapacity);
		pos = _start + len;//2更新pos指向
	}
	iterator end = _finish - 1;
	while (end >= pos)
	{
		*(end + 1) = *end;
		end--;
	}
	*pos = x;
	_finish++;
}

erase()

在这里插入图片描述

//vs下进行强制检查只要用过insert或erase后再次访问就会出错,但是gcc下不强制检查,有可能会正好正确,但是这是偶然性的
//erase以后迭代器失效了,不能访问
iterator erase(iterator pos)
{
	assert(pos >= begin() && pos < end());
	
	/*while (pos < end())
	{
		*pos = *(pos + 1);
		pos++;
	}*/
	iterator it = pos;
	while (it != _finish)
	{
		*(it) = *(it + 1);
		it++;
	}
	_finish--;
	//返回删除位置的下一个位置,其实在删除后就是pos位置
	return pos;
}

resize()

在这里插入图片描述

//C++模板对默认构造进行了升级,即使是内置类型也会有相应的默认构造
//所以这里是可以使用匿名对象的,即使T是内置类型
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++;*/
			*(_finish++) = val;
		}
	}
}

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

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

相关文章

JVM工作的总体机制概述

JDK、JRE、JVM关系回顾 JVM&#xff1a;Java Virtual Machine&#xff0c;翻译过来是Java虚拟机JRE&#xff1a;Java Runtime Environment&#xff0c;翻译过来是Java运行时环境 JREJVMJava程序运行时所需要的类库JDK&#xff1a;Java Development Kits&#xff0c;翻译过来是…

数据结构【图的类型定义和存储结构】

数据结构之图 图的定义和概念图的定义图的术语 图的类型定义图的存储结构数组&#xff08;邻接矩阵&#xff09;表示法无向图的邻接矩阵表示法有向图的邻接矩阵表示法网&#xff08;即有权图&#xff09;的邻接矩阵表示法 邻接矩阵的ADT定义邻接表&#xff08;链式&#xff09;…

测试经典书籍拆分讲解

一、全程软件测试 测试行业的经典书籍 测试方法测试策略领域测试主流测试技术涵盖了软件测试的流程与方法体系 二、探索式测试 探索式测试的经典代表性书籍探索式测试是业务测试和手工测试实践中的一个方法论 三、Google测试之道 高级测试工程师与架构师必读讲解google的测…

(学习笔记-进程管理)进程间有哪些通信方式?

每个进程的用户地址空间都是独立的&#xff0c;一般而言是不能互相访问的&#xff0c;但内核空间时每个进程都共享的&#xff0c;所以进程之间要通信必须通过内核 管道 在Linux命令中 [ | ] 这个竖线就是一个管道。 $ ps auxf | grep mysql 它的功能是讲前一个命令&#xf…

8月9日上课内容 nginx负载均衡

负载均衡工作当中用的很多的&#xff0c;也是面试会问的很重要的一个点 负载均衡&#xff1a;通过反向代理来实现&#xff08;nginx只有反向代理才能做负载均衡&#xff09; 正向代理的配置方法&#xff08;用的较少&#xff09; 反向代理的方式&#xff1a;四层代理与七层代…

C语言:打开调用堆栈

第一步&#xff1a;打断点 第二步&#xff1a;FnF5 第三步&#xff1a;按如图找到调用堆栈

DC-8靶机

DC-8官网地址 信息收集 靶机MAC&#xff1a; 00:0C:29:3A:46:A1 主机发现 nmap -sP 192.168.80.0/24端口扫描 nmap -A -p- 192.168.80.142访问80端口 点击页面能点击的地方&#xff0c;发现每点击一个链接&#xff0c;地址栏的?nid后面的数字就会变 尝试在数字后面加个 引…

【Leetcode】链表中两数之和(模拟加法器)(击败100%)

step by step. 题目&#xff1a; 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&…

2023年下半年软考初级程序员备考攻略

初级程序员考试科目包含基础知识和应用技术&#xff0c;各科目的考试形式都是笔试&#xff0c;满分均为75分。程序员考试需要各科目在一次考试中均及格才算合格&#xff0c;单科及格的成绩不保留&#xff0c;也不能转移到下次考试时使用。 这里给大家理清一个程序员考试的相关…

iOS开发-JsonModel的学习及使用

IOS JsonModel的学习及使用 当我们从服务端获取到json数据后的时候&#xff0c;我们需要在界面上展示或者保存起来&#xff0c;下面来看下直接通过NSDictionary取出数据的情况。 NSDictionary直接取出数据的诟病。 NSString *name [self.responseObj objectForKey:"nam…

Vue3弹出确认(Popconfirm)

效果如下图&#xff1a;在线预览 APIs 参数说明类型默认值必传title确认框的标题string | slot‘’falsedescription确认框的内容描述string | slot‘’falsecontent展示的文本string | slot‘’falseicon自定义弹出确认框 Icon 图标string | slot‘’falsemaxWidth弹出确认框…

《合成孔径雷达成像算法与实现》Figure3.8

与图3.7的代码区别只在于原始信号的表达式对了一个时间偏移 代码复现如下&#xff1a; clc clear all close all%参数设置 TBP 100; %时间带宽积 T 10e-6; %脉冲持续时间 tc …

SEED-Bench: Benchmarking Multimodal LLMs with Generative Comprehension

本文是LLM相关的文章&#xff0c;针对《SEED-Bench: Benchmarking Multimodal LLMs with Generative Comprehension》的翻译。 SEED-基准&#xff1a;用生成理解对多模式LLM进行基准测试 摘要1 引言2 相关工作3 SEED-Bench 摘要 基于强大的大型语言模型&#xff08;LLM&#…

【SpringBoot框架篇】33.优雅集成i18n实现国际化信息返回

文章目录 1.简介2.MessageSource配置和工具类封装2.1.配置MessageSource相关配置2.2.配置工具类2.3.测试返回国际级文本信息 3.不优雅的web调用示例(看看就行&#xff0c;别用)4.优雅使用示例4.1.错误响应消息枚举类4.2.ThreadLocal工具类配置4.2.1.ThreadLocal工具类数据封装4…

不再限制CPU,这才是Win11完全体的样子嘛

从 Win11 刚问世时&#xff0c;微软就宣称将给其许多 Win10没有也不会支持的新功能。 其中 Android 子系统的支持算得上是最期待&#xff0c;但结果难免有些失望的部分。 先不说使用怎么样&#xff0c;光是安装就困难重重。 绕过限制升级了 Win11 &#xff0c;但没想到安装 W…

idea双击启动无效,idea卡顿问题

idea双击启动无效&#xff1a;大概率是关机时没有正确关闭idea&#xff0c;再次开机导致无法正常启动idea 1.通过任务管理器杀死idea进程后重启idea 2.需要修改配置 打开 &#xff08;以各自电脑实际为准&#xff09;C:\Program Files\JetBrains\IntelliJ IDEA 2020.3.1\bin&am…

LabVIEW使用图像处理检测显微图像中的白血病

LabVIEW使用图像处理检测显微图像中的白血病 人体最重要的部分是血液&#xff0c;因为它使人活着。它执行许多重要功能&#xff0c;例如转移氧气&#xff0c;二氧化碳&#xff0c;矿物质等。血液量不足会极大地影响新陈代谢&#xff0c;如果不及早治疗&#xff0c;这可能是非常…

接口自动化测试框架及接口测试自动化主要知识点

接口自动化测试框架&#xff1a; 接口测试框架&#xff1a;使用最流行的Requests进行接口测试接口请求构造&#xff1a;常见的GET/POST/PUT/HEAD等HTTP请求构造 接口测试断言&#xff1a;状态码、返回内容等断言JSON/XML请求&#xff1a;发送json\xml请求JSON/XML响应断言&…

c语言经典例题讲解(输出菱形,喝汽水问题)

目录 一、输出菱形 二、喝汽水问题 方法1&#xff1a;一步一步来 方法二&#xff1a;直接套公式 一、输出菱形 输出类似于下图的菱形&#xff1a; 通过分析&#xff1a;1、先分为上下两部分输出 2.在输出前先输出空格 3.找规律进行输出 可知&#xff0c;可令上半部分lin…

Python Opencv实践 - 图像属性相关

import numpy as np import cv2 as cv import matplotlib.pyplot as pltimg cv.imread("../SampleImages/pomeranian.png", cv.IMREAD_COLOR) plt.imshow(img[:,:,::-1])#像素操作 pixel img[320,370] print(pixel)#只获取蓝色通道的值 pixel_blue img[320,370,0]…