vector类及模拟实现

SE80 Repository Information System 在 SAP CRM WebClient UI 组件分析中的实战指南 在 SAP CRM WebClient UI 开发过程中,如何快速定位组件、视图、上下文节点以及各类运行时对象,一直是调试效率的关键。(后文简称RIS)正是隐藏在SE80里的瑞士军刀,帮助开发者按照组件集、数据元素、上下文节点属性等多维条件进行交叉检索。官方博客将它描述为本文结合多年项目经验,系统梳理RIS的功能脉络与实战技巧,同时引入真实案例,示范如何借助它在几分钟内完成以往动辄数小时的排查任务。 阅读详情

目录

一.vector的使用

vector的构造函数

vector有关容量的函数

 vector的增删查改

动态二维数组的使用 

二.迭代器失效 (重点)

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

改变其底层空间的操作都有可能

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

 三.vector类的模拟实现


Vector 是 C++ STL 中最常用的容器之一,而使用STL的三个境界:第一境界是熟用,第二境界是了解泛型技术的内涵与STL的学理乃至实作,第三境界是能扩展STL。那么接下来我们学习vector也需要按照这种方法学习。

一.vector的使用

vector的构造函数

vector的构造函数有很多,但我们只要会我们常用的就可以了。

构造函数声明接口说明
vector()(重点)无参构造
vector(size_type n, const value_type& val =value_type())构造并初始化n个val
vector (const vector& x); (重点)拷贝构造
vector (InputIterator first, InputIterator last);使用迭代器进行初始化构

代码演示:

#include<iostream>
#include<vector>
using namespace std;
int main()
{
	vector<int>v1;//无参构造
	vector<int>v2(5, 1);//构造并初始化5个1
	for (auto& s : v2)
	{
		cout << s;
	}
	cout << endl;
	vector<int>v3(v2);//拷贝构造
	for (auto& s : v3)
	{
		cout << s;
	}
	cout << endl;
	vector<int>v4(v2.begin(), v2.end());//使用迭代器
	for (auto& s : v4)
	{
		cout << s;
	}
	cout << endl;
    return 0;
}

vector有关容量的函数

容量空间接口说明
size_t size( ) const;获取数据个数
size_t capacity() const;获取空间容量大小
bool empty() const;判空
void resize(size_t n,value_type val=value_type())改变vector的size
void reserve(size_t n);改变vector的capacity

代码演示:

#include<iostream>
#include<vector>
using namespace std;
int main1()
{
	vector<int>v2(5, 1);//构造并初始化5个1
	for (auto& s : v2)
	{
		cout << s;
	}
	cout << endl;
	cout << v2.size() << endl;
	cout << v2.capacity() << endl;
	cout << v2.empty() << endl;
	v2.resize(16, 2);
	cout << v2.capacity() << endl;
	for (auto& s : v2)
	{
		cout << s;
	}
	cout << endl;
	v2.reserve(45);
	cout << v2.capacity() << endl;
	return 0;
}

注意:以下这段测试vector的默认扩容机制代码在vs在g++下运行结果是不同的,以前我们常说扩容是按两倍扩的,但是在vector中vs下capacity是按1.5倍增长的,g++是按2倍增长的,所以我们不要固定化认为扩容都是两倍增长,具体增长多少也是根据具体需求定义的。

void TestVectorExpand()
{
	size_t sz;
	vector<int> v;
	sz = v.capacity();
	cout << "making v grow:\n";
	for (int i = 0; i < 100; ++i)
	{
		v.push_back(i);
		if (sz != v.capacity())
		{
			sz = v.capacity();
			cout << "capacity changed: " << sz << '\n';
		}
	}
}

reserve只负责开辟空间,如果知道需要多少空间,可以可以提前将空间设置足够, 就可以避免边插入边扩容导致效率低下的问题了。

resize再开空间的同时也会初始化,影响到size。

 vector的增删查改

 vector的增删查改接口说明
void push_back(size_t val);尾插
void pop_back();尾删

InputIterator find(InputIterator first,InputIterator last,const T&val);

查找。(不是vector的成员接口,而是通过算法模块实现的)
void insert(InputIterator pos,size_t val);在pos之前插入
InputIterator erase(InputIterator pos);删除pos位置的数据
swap交换两个vector数据空间
operator[]像数组一样访问

代码演示:

int main()
{
	vector<int>v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);//vector<int> v{1,2,3,4};
	for (auto& s : v)
	{
		cout << s<<' ';
	}
	cout << endl;
	auto ret = find(v.begin(),v.end(), 3);
	v.insert(ret, 89);
	auto it = v.begin();
	while (it != v.end())
	{
		cout << *it<<' ';
		it++;
	}
	cout << endl;
	v.pop_back();
	//v.erase(ret);
	auto pos = find(v.begin(), v.end(), 89);
	// 删除pos位置的数据
	v.erase(pos);
	for (auto& s : v)
	{
		cout << s << ' ';
	}
	cout << endl;
	vector<int>v1;
	v1.swap(v);
	for (auto& s : v1)
	{
		cout << s << ' ';
	}
	cout << endl;
	for (int i = 0; i < v1.size(); i++)
	{
		cout << v1[i] << ' ';
	}
	cout << endl;
	return 0;
}

动态二维数组的使用 

了解vector类的成员变量:T*_start(指向开头的指针),T*_finish(指向元素结尾的下一个的指针),T*_end_of_storage(指向容量大小的下一个的指针)。

vector<T>实际上是顺序表,顺序表底层是数组。 那么vector<vector<T>>就相当于二维数组。

可以用C++写一下杨辉三角:杨辉三角 

二.迭代器失效 (重点)

迭代器底层是一个指针,迭代器失效其实是指迭代器对应指针所指向的空间被销毁了,而使用一块已经被释放的空间,会导致程序崩溃。

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

改变其底层空间的操作都有可能

比如:resize,reserve,insert,assgin、push_back.

v.resize(100, 8):将有效元素个数增加到100个,多出的位置使用8填充,操作期间底层会扩容;
v.reserve(100):reserve的作用就是改变扩容大小但不改变有效元素个数,操作期间可能会引起底层容量改变;
v.insert(v.begin(), 0)/ v.push_back(8):插入元素期间,可能会引起扩容,而导致原空间被释放
v.assgin(100,8): 给vector重新赋值,可能会引起底层容量改变

就比如:

int main()
{
	vector<int>v{ 1,2,3,4 };
	auto it = v.begin();
	v.insert(it, 54);
	while (it != v.end())
	{
		cout << *it << ' ';
		it++;
	}
	cout << endl;
}

运行结果为:

程序崩溃。

insert会导致vector扩容,vector底层原理的旧空间被释放掉了,但是it还指向着那块被释放旧空间,所以在it迭代器操作时,访问了一块被释放的空间,所以程序崩溃。

解决方法为:更新迭代器(重新给it赋值)。

 

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

试着判断一下下面这段代码是否能运行成功呢?

int main()
{
int a[] = { 1, 2, 3, 4 };
vector<int> v(a, a + sizeof(a) / sizeof(int));
// 使用find查找3所在位置的iterator
vector<int>::iterator pos = find(v.begin(), v.end(), 3);
v.erase(pos);
cout << *pos << endl; 
return 0;
}

答案当然是不能了,为什么呢?迭代器pos被删除了,会导致编译器失效。就像如果pos刚好是最后一个元素,删完之后pos刚好是end位置,而end位置没有元素,所以pos迭代器已经被删除,打印*pos就是非法访问。

练习:

删除偶数

int main()
{
vector<int> v{ 1, 2, 3, 4 };
auto it = v.begin();
while (it != v.end())
{
if (*it % 2 == 0)
v.erase(it);
++it;
}
   
return 0;
}

判断一下代码是否能运行成功?并思考如果更改才能得到想要的结果。

答案是运行不成功的,因为erase删除了迭代器it,导致迭代器失效,已经失效的迭代器不能进行++,所以会导致程序崩溃。所以我们要怎么做呢?有同学说上面的代码也有问题,如果erase会把后面的数据往前面挪,那么再++会检查不到被删数据后面的一个数据。这是一个问题,但是改正后它还是出错,而且我们还没有更新迭代器。

int main()
{
	vector<int> v{ 1, 2, 3, 4 };
	auto it = v.begin();
	while (it != v.end())
	{
		if (*it % 2 == 0)
		{

			it=v.erase(it);//erase的返回值是被删迭代器的下一个迭代器
		}
		else
		++it;
	}
	return 0;
}

Linux下,g++对迭代器失效检查并不是特别严格。迭代器失效g++不一定会崩溃,只是运行结果不对,但是越界一定会崩溃。

 string类也和vector一样,对扩容操作和erase会导致迭代器失效,但都可以通过更新迭代器来解决。

 三.vector类的模拟实现

vector是向量类型,它可以容纳许多类型的数据,所以我们需要运用到模板。

vector.h

namespace slm
{
	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;
		}
		size_t size()const
		{
			return _finish - _start;
		}
		size_t capacity()const
		{
			return _end_of_storage - _start;
		}
		vector()
		{}
		~vector()
		{
			delete[]_start;
			_start = _finish = _end_of_storage = nullptr;
		}
		//v1(v2)
		vector(const vector<T>&v)
		{
			reserve(v.size());
			for (auto& e : v)
			{
				push_back(e);
			}
		}
		void swap(vector<T>& v)
		{
			std::swap(v._start, _start);
			std::swap(v._finish, _finish);
			std::swap(v._end_of_storage, _end_of_storage);
		}
		vector<T>& operator=(vector<T> v)
		{
			swap(v);
			return *this;
		}
		void resize(size_t n, const T& val = T())//T()为匿名对象
		{
			if (n < size())
			{
				_finish = _start + n;
			}
			else//大于或等于
			{
				reserve(n);
				while (_finish != _start + n)
				{
					*_finish = val;
					_finish++;
				}
			}
		}
		void reserve(size_t n)
		{
			if (n > capacity())
			{
				size_t oldsize = size();
				T* tmp = new T[n];
				//memcpy(tmp,_start,sizeof(T)*oldsize);
//memcpy是内存的二进制格式拷贝,将一段内存空间中内容原封不动的拷贝到另一段内存空间中。
//如果拷贝的是内置类型的元素,memcpy及高效也不会出错,
//但如果是自定义类型元素,并且自定义类型中涉及到资源管理时就会出错,
//因为memcpy的拷贝是浅拷贝。
				for (size_t i = 0; i < oldsize; i++)
				{
					tmp[i] = _start[i];
				}
				delete[]_start;
				_start = tmp;
				_finish = _start + oldsize;
				_end_of_storage = _start + n;
			}
		}
		T& operator[](size_t pos)
		{
			assert(pos < size());
			return _start[pos];
		}
		const T& operator[](size_t pos)const
		{
			assert(pos < size());
			return _start[pos];
		}
		void push_back(const T& x)
		{
			if (_finish  == _end_of_storage)
			{
				reserve(capacity() == 0 ? 4 : 2 * capacity());
			}
			*_finish = x;
			_finish++;
		}
		void pop_back()
		{
			assert(_finish > _start);
			_finish--;
		}
		void insert(iterator pos, const T& x)
		{
			//assert(pos-_start<size())//编译报错:有符号/无符号不匹配
			assert(pos<=_finish);
			assert(pos >= _start);
			//扩容会导致迭代器失效
			if (_finish == _end_of_storage)
			{
				size_t len = pos - _start;
				reserve(capacity() == 0 ? 4 : 2 * capacity());
				pos = _start + len;
			}
			iterator it = _finish - 1;
			while (it >= pos)
			{
				*(it + 1) = *it;
				it--;
			}
			_finish++;
			*pos = x;
		}
		iterator erase(iterator pos)
		{
			assert(pos <= _finish);
			assert(pos >= _start);
			iterator it = pos+1;
			while (it <= _finish)
			{
				*(it - 1) = *it;
				it++;
			}
			_finish--;
			return pos;
		}
	private:
		iterator _start=nullptr;
		iterator _finish=nullptr;
		iterator _end_of_storage=nullptr;
	};
}

test.cpp

namespace slm
{
	void test_vector()
	{
		vector<int> v1;
		v1.push_back(1);
		v1.push_back(2);
		v1.push_back(3);
		v1.push_back(4);
		for (auto& e : v1)
		{
			std::cout << e << ' ';
		}
		std::cout << std::endl;
		//测试size
		std::cout << v1.size() << std::endl;
		//测试capacity
		std::cout << v1.capacity() << std::endl;
		//测试resize
		v1.resize(6, 8);
		for (size_t i = 0; i < v1.size(); i++)
		{
			std::cout << v1[i] << ' ';
		}
		std::cout << std::endl;
		v1.resize(4, 9);
		for (size_t i = 0; i < v1.size(); i++)
		{
			std::cout << v1[i] << ' ';
		}
		std::cout << std::endl;
		//测试拷贝构造函数
		vector<int>v2(v1);
		for (auto& e : v2)
		{
			std::cout << e << ' ';
		}
		std::cout << std::endl;
		vector<int> v3;
		v3.push_back(5);
		v3.push_back(5);
		v3.push_back(5);
		v3.push_back(5);
		v3.push_back(5);
		v2 = v3;
		for (auto& e : v2)
		{
			std::cout << e << ' ';
		}
		std::cout << std::endl;
		v2.pop_back();
		for (auto& e : v2)
		{
			std::cout << e << ' ';
		}
		std::cout << std::endl;
		//测试insert
		v2.insert(v2.begin() + 2, 9);
		for (auto& e : v2)
		{
			std::cout << e << ' ';
		}
		std::cout << std::endl;
		v2.insert(v2.begin(), 6);
		for (auto& e : v2)
		{
			std::cout << e << ' ';
		}
		std::cout << std::endl;
		v2.insert(v2.end(), 7);
		for (auto& e : v2)
		{
			std::cout << e << ' ';
		}
		std::cout << std::endl;
		//测试erase
		v2.erase(v2.end());
		v2.erase(v2.begin());
		v2.erase(v2.begin() + 2);
		for (auto& e : v2)
		{
			std::cout << e << ' ';
		}
		std::cout << std::endl;
	}
}

int main()
{
	slm::test_vector();
	return 0;
}

YOLO11-Seg优化:卷积变体系列篇 | 动态蛇形卷积(Dynamic Snake Convolution) | ICCV2023 动态蛇形卷积(Dynamic Snake Convolution),增强微小特征提取能力,引入到YOLO11-Seg,与C3k2结合实现二次创新 阅读详情

相关推荐

Arduino+esp8266+blinker物联网开发

文章目录blinker点灯一.简介二.开发环境的搭建1.arduino的安装2.添加esp8266开发板3. blinker库的导入4.驱动的安装4.手机端安装app三.开发第一个点灯程序1.添加设备2.载入示例3.代码部分4.代码讲解5.程序烧写四.总结 blinker点灯 一.简介 为了加深为物联网知识的认识,今天就教大家如何用手机app来控制我们的开发板。我们的开发环境是以arduino I...

weixin_45631738的博客 3万+

vector类的模拟实现

vector的模拟实现,参考STL源代码,让你理解vector的大部分接口函数,更好的使用他们

2301_76895050的博客 1482

大疆控制算法笔试复习指南:从PID到MPC核心考点解析

控制算法是无人机、机器人等智能装备实现自主运行的核心技术。从经典控制到现代控制,PID控制算法、LQR控制算法、预测控制算法(MPC)以及Stanley控制算法等,构成了工程实践中不可或缺的方法体系。理解其数学原理、适用条件与调参逻辑,是评估系统稳定性、动态响应与抗扰能力的基础。在无人机飞控、云台增稳、车载路径跟踪等典型场景中,这些算法直接决定了设备的实际性能表现。大疆等企业相关岗位的笔试,正是围绕上述核心知识点,考查候选人对控制系统本质的理解、数学推导能力以及工程实现素养。本文整理了一套覆盖理论基石、高频

weixin_33178839的博客 359

C++vector类的模拟实现

C++vector类的模拟实现,让你从底层深刻认识vector!!!

wer24_25的博客 1355

QCM6490平台DDR测试:从QDUTT配置到眼图分析的实战指南

本文详细介绍了QCM6490平台DDR测试的全流程,从QDUTT工具安装配置到眼图分析,提供了实战操作指南和常见问题解决方案。通过具体案例分享,帮助工程师掌握DDR测试技巧,确保内存稳定性,特别适用于物联网和边缘计算设备的开发调试。

weixin_33910191的博客 458

cadence virtuoso 激励信号源

vpulse,vpwl,vsin,vsource信号源介绍

努力学习的IC小白 3万+

C++—vector类的使用及模拟实现

C++vector类的使用及模拟实现部分函数讲解

渣檬Charman的博客 1167

Cilium动手实验室: 精通之旅---1.Getting Started with Cilium

我们需要在 HTTP 层的第 7 层实施策略,以限制允许 tiefighter 调用的确切 API,以及不允许调用哪些 API。上仅需要的 API 资源的访问,从而为微服务之间的通信实施“最低权限”安全方法。船只上进行匹配,因此我们需要在该标签上进行匹配,此外,我们必须确保来自带有标签。为了模拟我们的连接测试,我们将使用 curl 执行简单的 API 调用。在我们立即开始更改策略之前,让我们考虑一下相应的网络策略应该是什么样子。的规则,该规则将通过 L3-L4 策略对死星的访问限制为仅帝国船只。

Q先生 1126

【C++】vector 类模拟实现:探索动态数组的奥秘

本文围绕 C++ 中 vector 类的模拟实现展开。首先在引言中强调其重要性并引发探索兴趣。接着分析 vector 类功能需求,涵盖存储、访问修改、数量操作、迭代器支持与内存管理等方面。然后详细阐述模拟实现步骤及代码,包括类定义、多种构造函数、析构函数、各功能函数(如获取数量容量、预留调整大小、下标操作符重载、赋值、添加删除元素、迭代器相关)。还给出示例用法展示各类操作的实际应用,最后总结模拟实现的意义,并通过投票环节收集读者对文章内容理解及后续期望等方面的反馈。

A Charmer 的博客 1831

AI Agent 架构的底层原理与核心机制

AI Agent五层架构实现智能闭环运转:1)感知层负责多模态信息输入与预处理;2)记忆层分类存储短期/长期记忆及知识库;3)认知层通过ReAct推理和反思机制进行决策规划;4)工具层调用外部API扩展能力边界;5)执行层完成任务输出并形成反馈闭环。五层架构通过"输入-处理-输出-优化"的联动机制,使Agent具备自主决策、持续学习和任务执行能力,突破传统LLM的局限,实现从信息处理到实际落地的完整智能体系。

女王の专属领地 495

【Autosar COM】Marvell 88Q5050 以太网交换机驱动技术解析

本驱动实现了对Marvell 88Q5050交换机的全面控制,通过模块化设计满足AUTOSAR规范要求。增加DMA加速机制提升大数据量处理性能实现TSN(时间敏感网络)特性支持引入异步通知机制替代轮询操作增强安全特性,如MACsec支持该驱动架构为车载以太网交换机控制提供了可靠基础,其设计思想可推广到其他车载网络控制器开发中。随着车载网络技术的演进,驱动需持续迭代以支持新特性与更高通信速率需求。

1450

C++ vector 类的使用与模拟实现

本文介绍了C++中vector容器的使用与底层实现。vector作为动态数组容器,具有连续存储、自动扩容等特性,支持高效随机访问。文章详细讲解了vector的构造方法、迭代器使用、空间管理(resize/reserve)以及增删查改操作,重点分析了迭代器失效问题及其解决方案。同时通过模拟实现vector的核心功能(包括三个指针管理、深拷贝、扩容策略等),深入剖析了vector的底层原理。最后比较了vector与数组、string的区别,帮助开发者根据需求选择合适的容器。掌握vector的使用技巧和实现原理,

2403_87856518的博客 1191

【深度学习驱动流体力学】OpenFOAM目录流体力学求解器汇总介绍

下面这些目录结构和其中的求解器和工具展示了OpenFOAM作为一个功能强大且广泛应用的开源CFD软件框架的多样性和灵活性。每个求解器都专门用于解决不同类型的流体动力学问题,从基础的流动模拟到复杂的多相流动和燃烧模拟等各种应用场景。

源代码杀手的博客 1184

【C++】vector类的模拟实现

#include <iostream> #include <cassert> using namespace std; template <class T> class Vector { public: typedef T* iterator; Vector() :_start(nullptr) , _finish(nullptr) , ...

进阶之路 519

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

vector类模拟实现

模拟实现vector

2301_80030944的博客 321

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

38 vector类 & 模拟实现

学习总结,附vector模拟实现源码

m0_66277256的博客 943

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

STL之vector类的模拟实现

目录1. vector的成员变量 2. vector的成员函数 2.1. vector的迭代器 2.2. vector的初始化与销毁 2.2.1. 构造函数与拷贝构造2.2.2. 赋值重载与析构函数 2.3. vector的容量操作 2.3.1. 有效长度与容量大小2.3.2. 容量操作 2.4. vector的访问操作 2.5. vector的修改操作 2.5.1. 常见的修改操作 3. 源码 3.1 vector.h 3.2 test.cpp 3.3 运行结果

2302_80220709的博客 755

C++之vector类的模拟实现

这些成员变量用于管理vector内部的动态数组 (1)_start:这是一个指针,指向分配给vector的内存区域的开始。这是数组的第一个元素。 (2)_finish:这个指针指向数组中最后一个实际存在的元素的下一个位置。这意味着它指向结束后的第一个元素,它用来表示存储在vector中的实际元素的结束。 (3)_end_of_storage:这个指针指向分配给vector的内存块的末尾。这不是最后一个有效元素的位置,而是整个内存块的结束位置,在这之后可能会有额外的未初始化空间,预留以实现当vector

夏天的阳光吖的博客 831

C++中的vector类模拟实现

涉及到一个赋值运算,而string类本身已经重载过赋值运算符,所以是深拷贝,但是模拟类还没有实现赋值运算符的重载,所以在这里赋值时实际上还是调用的编译器默认的赋值运算符重载函数,依旧是浅拷贝,导致拷贝的结果也就是新对象装着被拷贝对象的旧内容,所以需要实现赋值运算符重载函数。需要注意的是,设计初始化值时,不要直接使用值,而是使用匿名对象调用对应的构造函数,因为vector中存储的数据类型不一定时内置类型,也有可能是自定义类型。有了迭代器区间的构造函数后,使用根据个数的构造函数将会出问题,下面是测试报错信息。

小何代码咖啡馆 1172

【C++】简单学——vector类(模拟实现)

vector的模拟实现,包括常用的方法模拟和迭代器失效问题以及教你怎样去自己模拟实现vector

m0_73724954的博客 1027

【C++】vector(下):vector类的模拟实现(含迭代器失效问题)

vector类的常用接口的模拟实现 以及 vector 迭代器失效问题。【C++】vector(上):vector的常用接口介绍。

无限进步!!! 1515

【C++】vector类模拟实现

vector的模拟实现

qq_66314292的博客 1708

C++初阶-vector类的模拟实现

因为增容中使用了memcpy,memcpy导致了问题的出现,因为memcpy是按字节拷贝的,它本质上造成了浅拷贝问题,memcpy使新旧空间都指向了一份数据,旧空间释放后,它指向的对应数据也被释放,而新空间指针还是指向这份旧空间,这就造成了非法访问,所以新空间与旧空间不应该指向同一份数据,应该不用memcopy,写成。(1)释放原空间,新开一块容量和v一样大的空间,更新_start,_finish,_end_of_storage。

sushang的博客 1184

C++学习之路,从0到精通的征途:vector类的模拟实现

源文档。

ll778811的博客 1329

【C++】:STL源码剖析之vector类容器的底层模拟实现

如果没有备用空间了,就扩充空间(重新配置、搬移数据、释放原空间)。注意 : 将数据拷贝到新空间,仍然不能用memcpy函数,因为对于需要深拷贝的自定义类型,使用memcpy函数以后,新开辟空间里的元素和原空间里的元素所指向的内存空间是一样的,当旧空间被释放时,会调用自定义类型的析构函数,从而使得新开辟空间里的元素指向的内存空间也被释放掉了。1). 新开辟一块空间,若容器为空,将_start,_finish指向新开辟空间的首元素地址, _endofstorage指向新开辟空间的最后一个元素下一个位置。

优快云官方认证C/C++研发领域优质创作者 优快云官方2023年成都赛道Top3 第16届蓝桥杯C/C++软件赛四川赛区二等奖 带你玩转C/C++ 数据结构与算法 Linux系统编程/Linux网络编程 MySQL数据库 软件测试开发 2770

STL库——vector(类模拟实现)

本文介绍了如何模拟实现C++中的vector容器,主要包括基本框架、构造函数、析构函数、运算符重载、增删查改等核心功能。通过自定义三个指针变量(_start、_finish、_end_of_storage)来管理内存空间,详细讲解了push_back、pop_back、insert、erase等操作的实现细节,特别强调了迭代器失效问题及其解决方案。同时文章还实现了reserve、resize等容量管理函数,并讨论了深拷贝与浅拷贝在扩容时的关键区别。

Linux、C++、图形软件开发等。不一定每次都能写出完美的代码,但会认真搞懂每一个问题。 1057
上一篇: string类
下一篇: stack/queue/priority_queue类
噜啦噜啦嘞好
博客等级 码龄3年 212粉丝 39原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值